Struct TokenRefCell

Source
pub struct TokenRefCell<T: ?Sized, Tk: Token + ?Sized = BoxToken> { /* private fields */ }
Expand description

Interior mutability cell using an external Token reference to synchronize accesses.

Contrary to other standard cells like RefCell, TokenRefCell is Sync as long as its token is Send + Sync.

§Memory layout

TokenRefCell<T> has the same in-memory representation as its inner type T when Token::Id is ().

Implementations§

Source§

impl<T, Tk: Token + ?Sized> TokenRefCell<T, Tk>

Source

pub fn new(value: T, token: &Tk) -> Self
where <<<Tk as Token>::Id as TokenId>::CellRepr as CellRepr<Tk::Id>>::Cell<T>: Sized,

Creates a new TokenRefCell containing a value, synchronized by the given token.

Examples found in repository?
examples/graph.rs (line 98)
96    fn new_cell(id: NodeId, token: &BoxToken) -> Arc<TokenRefCell<Node>> {
97        let edges = HashMap::new();
98        Arc::new(TokenRefCell::new(Node { id, edges }, token))
99    }
Source

pub fn new_const(value: T) -> Self
where Tk: Token<Id = ()>,

Creates a new TokenRefCell containing a value, synchronized by a const token.

Source

pub fn with_token_id(value: T, token_id: Tk::Id) -> Self
where <<<Tk as Token>::Id as TokenId>::CellRepr as CellRepr<Tk::Id>>::Cell<T>: Sized,

Creates a new TokenRefCell containing a value, synchronized by a token with the given id.

It allows creating TokenRefCell when token is already borrowed.

Source

pub fn into_inner(self) -> T
where <<<Tk as Token>::Id as TokenId>::CellRepr as CellRepr<Tk::Id>>::Cell<T>: Sized,

Consumes the TokenRefCell, returning the wrapped value.

Source§

impl<T: ?Sized, Tk: Token + ?Sized> TokenRefCell<T, Tk>

Source

pub fn borrow<'a>(&'a self, token: &'a Tk) -> Ref<'a, T, Tk>

Immutably borrows the wrapped value using a shared reference to the token.

The token reference is reborrowed in the returned Ref, preventing any aliasing mutable borrow. Multiple immutable borrows can be taken out at the same time.

The check runtime cost is only a token id comparison (when the token is not a singleton_token!); there is no write, contrary to RefCell or locks.

§Panics

Panics if the token doesn’t match the one used at cell initialization (or set with set_token). For a non-panicking variant, use try_borrow.

Examples found in repository?
examples/graph.rs (line 30)
29    pub fn get_node(&self, id: NodeId) -> Option<&Node> {
30        Some(self.nodes.get(&id)?.borrow(&self.token).into_ref())
31    }
Source

pub fn try_borrow<'a>( &'a self, token: &'a Tk, ) -> Result<Ref<'a, T, Tk>, BorrowError>

Tries to immutably borrow the wrapped value using a shared reference to the token.

Returns an error if the token doesn’t match the one used at cell initialization (or set with set_token). This is the non-panicking variant of borrow.

The token reference is reborrowed in the returned Ref, preventing any aliasing mutable borrow. Multiple immutable borrows can be taken out at the same time.

The check runtime cost is only a token id comparison (when the token is not a singleton_token!); there is no write, contrary to RefCell or locks.

Source

pub fn borrow_mut<'a>(&'a self, token: &'a mut Tk) -> RefMut<'a, T, Tk>

Mutably borrows the wrapped value using an exclusive reference to the token.

The token reference is reborrowed in the returned RefMut, preventing any aliasing mutable/immutable borrow.

The check runtime cost is only a token id comparison (when the token is not a singleton_token!), as well as a token unicity check (mostly a noop for most of the token implementations); there is no write, contrary to RefCell or locks.

§Panics

Panics if the token doesn’t match the one used at cell initialization (or set with set_token), or if the token is not unique. For a non-panicking variant, use try_borrow.

Examples found in repository?
examples/graph.rs (line 44)
40    pub fn remove_node(&mut self, id: NodeId) -> bool {
41        let Some(node) = self.nodes.remove(&id) else {
42            return false;
43        };
44        let mut node_mut = node.borrow_mut(&mut self.token);
45        let mut reborrow_mut =
46            node_mut.reborrow_stateful_mut(|node| node.edges.values().map(AsRef::as_ref));
47        while let Some(mut other) = reborrow_mut.reborrow_opt_mut(|edges| edges.next()) {
48            other.edges.remove(&id);
49        }
50        true
51    }
52
53    pub fn insert_edge(&mut self, node1: NodeId, node2: NodeId) {
54        let mut node = |id| {
55            let entry = self.nodes.entry(id);
56            let node = entry.or_insert_with(|| Node::new_cell(node1, &self.token));
57            node.clone()
58        };
59        let node_cell1 = node(node1);
60        let node_cell2 = node(node2);
61        node_cell1
62            .borrow_mut(&mut self.token)
63            .edges
64            .insert(node2, node_cell2.clone());
65        node_cell2
66            .borrow_mut(&mut self.token)
67            .edges
68            .insert(node1, node_cell1);
69    }
70
71    pub fn remove_edge(&mut self, node1: NodeId, node2: NodeId) {
72        let mut remove = |a, b| {
73            let Some(node) = self.nodes.get(&a) else {
74                return false;
75            };
76            node.borrow_mut(&mut self.token).edges.remove(&b);
77            true
78        };
79        if remove(node1, node2) {
80            remove(node2, node1);
81        }
82    }
Source

pub fn try_borrow_mut<'a>( &'a self, token: &'a mut Tk, ) -> Result<RefMut<'a, T, Tk>, BorrowMutError>

Mutably borrows the wrapped value using an exclusive reference to the token.

Returns an error if the token doesn’t match the one used at cell initialization (or set with set_token), or if the token is not unique. For a non-panicking variant, use try_borrow.

The token reference is reborrowed in the returned RefMut, preventing any aliasing mutable/immutable borrow.

The check runtime cost is only a token id comparison (when the token is not a singleton_token!), as well as a token unicity check (mostly a noop for most of the token implementations); there is no write, contrary to RefCell or locks.

Examples found in repository?
examples/graph.rs (line 87)
84    pub fn clear(&mut self) {
85        let mut nodes = mem::take(&mut self.nodes);
86        for (_, node) in nodes.drain() {
87            if let Ok(mut node) = node.try_borrow_mut(&mut self.token) {
88                node.edges.clear();
89            }
90        }
91        self.nodes = nodes;
92    }
Source

pub fn as_ptr(&self) -> *mut T

Gets a mutable pointer to the wrapped value.

Source

pub fn get_mut(&mut self) -> &mut T

Returns a mutable reference to the underlying data.

Source

pub fn from_ref(t: &mut T) -> &Self
where Tk: Token<Id = ()>,

Returns a &TokenRefCell<T, Tk> from a &mut T

Source

pub fn set_token(&mut self, token: &Tk)

Set a new token to synchronize the cell.

Source

pub fn token_id(&self) -> Tk::Id

Get the id of the token by which the cell is synchronized.

Source

pub fn set_token_id(&mut self, token_id: Tk::Id)

Set a new token_id to synchronize the cell.

Source§

impl<T, Tk: Token<Id = ()> + ?Sized> TokenRefCell<[T], Tk>

Source

pub fn as_slice_of_cells(&self) -> &[TokenRefCell<T, Tk>]
where Tk: Token<Id = ()>,

Returns a &[TokenRefCell<T>] from a &TokenRefCell<[T]>

Trait Implementations§

Source§

impl<T: ?Sized, Tk: Token + ?Sized> AsRef<TokenRefCell<T, Tk>> for &TokenRefCell<T, Tk>

Source§

fn as_ref(&self) -> &TokenRefCell<T, Tk>

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<T: ?Sized + Debug, Tk: Token + ?Sized> Debug for TokenRefCell<T, Tk>
where Tk::Id: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: ?Sized + Sync, Tk> Sync for TokenRefCell<T, Tk>
where Tk: Send + Sync + Token + ?Sized,

Auto Trait Implementations§

§

impl<T, Tk> Freeze for TokenRefCell<T, Tk>
where <<<Tk as Token>::Id as TokenId>::CellRepr as CellRepr<<Tk as Token>::Id>>::Cell<T>: Freeze, T: ?Sized, Tk: ?Sized,

§

impl<T, Tk> RefUnwindSafe for TokenRefCell<T, Tk>
where <<<Tk as Token>::Id as TokenId>::CellRepr as CellRepr<<Tk as Token>::Id>>::Cell<T>: RefUnwindSafe, T: ?Sized, Tk: ?Sized,

§

impl<T, Tk> Send for TokenRefCell<T, Tk>
where <<<Tk as Token>::Id as TokenId>::CellRepr as CellRepr<<Tk as Token>::Id>>::Cell<T>: Send, T: ?Sized, Tk: ?Sized,

§

impl<T, Tk> Unpin for TokenRefCell<T, Tk>
where <<<Tk as Token>::Id as TokenId>::CellRepr as CellRepr<<Tk as Token>::Id>>::Cell<T>: Unpin, T: ?Sized, Tk: ?Sized,

§

impl<T, Tk> UnwindSafe for TokenRefCell<T, Tk>
where <<<Tk as Token>::Id as TokenId>::CellRepr as CellRepr<<Tk as Token>::Id>>::Cell<T>: UnwindSafe, T: ?Sized, Tk: ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.