1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
use std::cell::Cell;
use crate::NodeId;
/// A node id or none in one word, where `Cell<Option<NodeId>>` takes two: a
/// layout node keeps three, and the 24 bytes kept it out of jemalloc's
/// 640-byte size class.
pub struct NodeIdCell(Cell<NodeId>);
// The id a cell holds for none: no node gets it, as ids index the applier's
// nodes.
const NONE: NodeId = NodeId(usize::MAX);
impl NodeIdCell {
/// A cell holding `id`.
pub const fn new(id: Option<NodeId>) -> Self {
Self(Cell::new(match id {
Some(id) => id,
None => NONE,
}))
}
/// The id the cell holds.
pub fn get(&self) -> Option<NodeId> {
// With `then_some`, LLVM compiles the composer's group opening five
// instructions longer a group.
Some(self.0.get()).filter(|&id| id != NONE)
}
/// Puts `id` in the cell.
pub fn set(&self, id: Option<NodeId>) {
debug_assert_ne!(id, Some(NONE), "no node takes the none id");
self.0.set(id.unwrap_or(NONE));
}
/// Puts `id` in the cell and returns the id it held.
pub fn replace(&self, id: Option<NodeId>) -> Option<NodeId> {
let previous = self.get();
self.set(id);
previous
}
}