Struct kernel::utilities::cells::MapCell

source ·
pub struct MapCell<T> {
    val: UnsafeCell<MaybeUninit<T>>,
    occupied: Cell<MapCellState>,
}
Expand description

A mutable, possibly unset, memory location that provides checked &mut access to its contents via a closure.

A MapCell provides checked shared access to its mutable memory. Borrow rules are enforced by forcing clients to either move the memory out of the cell or operate on a &mut within a closure. You can think of a MapCell as a Cell<Option<T>> with an extra “in-use” state to prevent map from invoking undefined behavior when called re-entrantly.

§Examples

let cell: MapCell<i64> = MapCell::empty();

assert!(cell.is_none());
cell.map(|_| unreachable!("The cell is empty; map does not call the closure"));
assert_eq!(cell.take(), None);
cell.put(10);
assert_eq!(cell.take(), Some(10));
assert_eq!(cell.replace(20), None);
assert_eq!(cell.get(), Some(20));

cell.map(|x| {
    assert_eq!(x, &mut 20);
    // `map` provides a `&mut` to the contents inside the closure
    *x = 30;
});
assert_eq!(cell.replace(60), Some(30));

Fields§

§val: UnsafeCell<MaybeUninit<T>>§occupied: Cell<MapCellState>

Implementations§

source§

impl<T> MapCell<T>
where T: Copy,

source

pub fn get(&self) -> Option<T>

Gets the contents of the cell, if any.

Returns None if the cell is empty.

This requires the held type be Copy for the same reason Cell::get does: it leaves the contents of self intact and so it can’t have drop glue.

This returns None in release mode if the MapCell’s contents are already borrowed.

§Examples
let cell: MapCell<u32> = MapCell::empty();
assert_eq!(cell.get(), None);

cell.put(20);
assert_eq!(cell.get(), Some(20));
§Panics

If debug assertions are enabled, this panics if the MapCell’s contents are already borrowed.

source§

impl<T> MapCell<T>

source

pub const fn empty() -> MapCell<T>

Creates an empty MapCell.

source

pub const fn new(value: T) -> MapCell<T>

Creates a new MapCell containing value.

source

pub fn is_none(&self) -> bool

Returns true if the MapCell contains no value.

§Examples
let x: MapCell<i32> = MapCell::empty();
assert!(x.is_none());

x.put(10);
x.map(|_| assert!(!x.is_none()));
assert!(!x.is_none());
source

pub fn is_some(&self) -> bool

Returns true if the MapCell contains a value.

§Examples
let x: MapCell<i32> = MapCell::new(10);
assert!(x.is_some());
x.map(|_| assert!(x.is_some()));

x.take();
assert!(!x.is_some());
source

pub fn take(&self) -> Option<T>

Takes the value out of the MapCell, leaving it empty.

Returns None if the cell is empty.

To save size, this has no effect and returns None in release mode if the MapCell’s contents are already borrowed.

§Examples
let cell = MapCell::new(1234);
let x = &cell;
let y = &cell;

assert_eq!(x.take(), Some(1234));
assert_eq!(y.take(), None);
§Panics

If debug assertions are enabled, this panics if the MapCell’s contents are already borrowed.

source

pub fn put(&self, val: T)

Puts a value into the MapCell without returning the old value.

To save size, this has no effect in release mode if map is invoking a closure for this cell.

§Panics

If debug assertions are enabled, this panics if the MapCell’s contents are already borrowed.

source

pub fn replace(&self, val: T) -> Option<T>

Replaces the contents of the MapCell, returning the old value if available.

To save size, this has no effect and returns None in release mode if the MapCell’s contents are already borrowed.

§Panics

If debug assertions are enabled, this panics if the MapCell’s contents are already borrowed.

source

pub fn map<F, R>(&self, closure: F) -> Option<R>
where F: FnOnce(&mut T) -> R,

Calls closure with a &mut of the contents of the MapCell, if available.

The closure is only called if the MapCell has a value. The state of the MapCell is unchanged after the closure completes.

§Re-entrancy

This borrows the contents of the cell while the closure is executing. Be careful about calling methods on &self inside of that closure! To save size, this has no effect in release mode, but if debug assertions are enabled, this panics to indicate a likely bug.

§Examples
let cell = MapCell::new(1234);
let x = &cell;
let y = &cell;

x.map(|value| {
    // We have mutable access to the value while in the closure
    *value += 1;
});

// After the closure completes, the mutable memory is still in the cell,
// but potentially changed.
assert_eq!(y.take(), Some(1235));
§Panics

If debug assertions are enabled, this panics if the MapCell’s contents are already borrowed.

source

pub fn map_or<F, R>(&self, default: R, closure: F) -> R
where F: FnOnce(&mut T) -> R,

Behaves like map, but returns default if there is no value present.

source

pub fn and_then<F, R>(&self, closure: F) -> Option<R>
where F: FnOnce(&mut T) -> Option<R>,

Behaves the same as map, except the closure is allowed to return an Option.

source

pub fn modify_or_replace<F, G>(&self, modify: F, mkval: G)
where F: FnOnce(&mut T), G: FnOnce() -> T,

If a value is present modify is called with a borrow. Otherwise, the value is set with G.

Trait Implementations§

source§

impl<T> Drop for MapCell<T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for MapCell<T>

§

impl<T> !RefUnwindSafe for MapCell<T>

§

impl<T> Send for MapCell<T>
where T: Send,

§

impl<T> !Sync for MapCell<T>

§

impl<T> Unpin for MapCell<T>
where T: Unpin,

§

impl<T> UnwindSafe for MapCell<T>
where T: UnwindSafe,

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>,

§

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>,

§

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.