Struct ghost_cell::ghost_cell::GhostCell
source · [−]#[repr(transparent)]pub struct GhostCell<'brand, T: ?Sized> { /* private fields */ }
Expand description
Branded wrapper for a value, whose type is T
.
A GhostCell<'x, T>
owns an instance of type T
:
- Unique access to the cell allows unimpeded access to the contained value.
- Shared access to the cell requires mediating access through the associated
GhostToken<'x, T>
which will enforce at compile-time the aliasing XOR mutability safety property.
Implementations
sourceimpl<'brand, T> GhostCell<'brand, T>
impl<'brand, T> GhostCell<'brand, T>
sourcepub const fn new(value: T) -> Self
pub const fn new(value: T) -> Self
Wraps some T
into a GhostCell
with brand 'brand
which associates it to one, and only one, GhostToken
.
Example
use ghost_cell::{GhostToken, GhostCell};
GhostToken::new(|token| {
let cell = GhostCell::new(42);
assert_eq!(42, *cell.borrow(&token));
});
sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Turns an owned GhostCell
back into owned data.
Example
use ghost_cell::{GhostToken, GhostCell};
let value = GhostToken::new(|mut token| {
let cell = GhostCell::new(42);
cell.into_inner()
});
assert_eq!(42, value);
sourceimpl<'brand, T: ?Sized> GhostCell<'brand, T>
impl<'brand, T: ?Sized> GhostCell<'brand, T>
sourcepub fn borrow<'a>(&'a self, _: &'a GhostToken<'brand>) -> &'a T
pub fn borrow<'a>(&'a self, _: &'a GhostToken<'brand>) -> &'a T
Immutably borrows the GhostCell
with the same-branded token.
Example
use ghost_cell::{GhostToken, GhostCell};
let n = 12;
let value = GhostToken::new(|mut token| {
let cell = GhostCell::new(42);
let vec: Vec<_> = (0..n).map(|_| &cell).collect();
let one: &i32 = vec[1].borrow(&token);
let two: &i32 = vec[2].borrow(&token);
*one + *two
});
assert_eq!(84, value);
sourcepub fn borrow_mut<'a>(&'a self, _: &'a mut GhostToken<'brand>) -> &'a mut T
pub fn borrow_mut<'a>(&'a self, _: &'a mut GhostToken<'brand>) -> &'a mut T
Mutably borrows the GhostCell
with the same-branded token.
Example
use ghost_cell::{GhostToken, GhostCell};
let n = 12;
let value = GhostToken::new(|mut token| {
let cell = GhostCell::new(42);
let vec: Vec<_> = (0..n).map(|_| &cell).collect();
let reference: &mut i32 = vec[n / 2].borrow_mut(&mut token);
*reference = 33;
*cell.borrow(&token)
});
assert_eq!(33, value);
sourcepub fn get_mut(&mut self) -> &mut T
pub fn get_mut(&mut self) -> &mut T
Turns a mutably borrowed GhostCell
into mutably borrowed data.
self
is mutably borrowed for the lifetime of the result, ensuring the absence of aliasing.
Example
use ghost_cell::{GhostToken, GhostCell};
let value = GhostToken::new(|mut token| {
let mut cell = GhostCell::new(42);
*cell.get_mut() = 33;
*cell.borrow(&token)
});
assert_eq!(33, value);
sourcepub fn from_mut(t: &mut T) -> &mut Self
pub fn from_mut(t: &mut T) -> &mut Self
Turns mutably borrowed data into a mutably borrowed GhostCell
.
t
is mutably borrowed for the lifetime of the result, ensuring the absence of aliasing.
Example
use ghost_cell::{GhostToken, GhostCell};
let n = 12;
let mut value = 42;
GhostToken::new(|mut token| {
let cell = GhostCell::from_mut(&mut value);
let vec: Vec<_> = (0..n).map(|_| &cell).collect();
*vec[n / 2].borrow_mut(&mut token) = 33;
});
assert_eq!(33, value);
sourceimpl<'brand, T> GhostCell<'brand, T>
impl<'brand, T> GhostCell<'brand, T>
sourcepub fn replace(&self, value: T, token: &mut GhostToken<'brand>) -> T
pub fn replace(&self, value: T, token: &mut GhostToken<'brand>) -> T
Returns the value, replacing it by the supplied one.
Example
use ghost_cell::{GhostToken, GhostCell};
let n = 12;
let value = GhostToken::new(|mut token| {
let cell = GhostCell::new(42);
let vec: Vec<_> = (0..n).map(|_| &cell).collect();
let previous = vec[n / 2].replace(33, &mut token);
assert_eq!(42, previous);
*cell.borrow(&token)
});
assert_eq!(33, value);
sourcepub fn take(&self, token: &mut GhostToken<'brand>) -> Twhere
T: Default,
pub fn take(&self, token: &mut GhostToken<'brand>) -> Twhere
T: Default,
Returns the value, replacing it with the default value.
Example
use ghost_cell::{GhostToken, GhostCell};
let n = 12;
let value = GhostToken::new(|mut token| {
let cell = GhostCell::new(42);
let vec: Vec<_> = (0..n).map(|_| &cell).collect();
let previous = vec[n / 2].take(&mut token);
assert_eq!(42, previous);
*cell.borrow(&token)
});
assert_eq!(0, value);
sourceimpl<'brand, T> GhostCell<'brand, [T]>
impl<'brand, T> GhostCell<'brand, [T]>
sourcepub fn as_slice_of_cells(&self) -> &[GhostCell<'brand, T>]
pub fn as_slice_of_cells(&self) -> &[GhostCell<'brand, T>]
Returns a slice of cells from a cell containing a slice.
Example
use ghost_cell::{GhostToken, GhostCell};
let n = 12;
let value = GhostToken::new(|mut token| {
let mut vec: Vec<_> = (0..n).collect();
let cell = GhostCell::from_mut(&mut vec[..]);
let slice = cell.as_slice_of_cells();
*slice[n / 2].borrow_mut(&mut token) = 33;
vec[n / 2]
});
assert_eq!(33, value);
Trait Implementations
impl<'brand, T: ?Sized + Send> Send for GhostCell<'brand, T>
A GhostCell<'_, T>
owns a T
, so it cannot be sent across threads if T
cannot.
Conversely, a GhostCell
does not add any state on top of T
, so if T
can be sent across threads, so can
GhostCell<'_, T>
impl<'brand, T: ?Sized + Send + Sync> Sync for GhostCell<'brand, T>
A GhostCell<'_, T>
owns a T
, so it cannot be accessed from different threads if T
cannot.
Conversely, a GhostCell
does not add any state on top of T
, so if T
can be accessed from different threads,
so can GhostCell<'_, T>
. T
also needs to be sendable across threads,
because a T
can be extracted from a &GhostCell<'brand, T>
via GhostCell::replace
.