use std::ops;
use index_vec::IndexVec;
use toasty_core::stmt;
use super::Node;
#[derive(Debug)]
pub(crate) struct Store {
slots: IndexVec<NodeId, Slot>,
}
#[expect(clippy::large_enum_variant)]
#[derive(Debug)]
enum Slot {
Reserved,
Node(Node),
}
index_vec::define_index_type! {
pub(crate) struct NodeId = u32;
}
impl Store {
pub(crate) fn new() -> Store {
Store {
slots: IndexVec::new(),
}
}
pub(crate) fn insert(&mut self, node: impl Into<Node>) -> NodeId {
self.slots.push(Slot::Node(node.into()))
}
pub(crate) fn insert_with_deps<I>(&mut self, node: impl Into<Node>, deps: I) -> NodeId
where
I: IntoIterator<Item = NodeId>,
{
let mut node = node.into();
node.deps.extend(deps);
self.slots.push(Slot::Node(node))
}
pub(crate) fn reserve(&mut self) -> NodeId {
self.slots.push(Slot::Reserved)
}
#[track_caller]
pub(crate) fn fill(&mut self, id: NodeId, node: impl Into<Node>) {
let slot = &mut self.slots[id];
assert!(
matches!(slot, Slot::Reserved),
"fill of non-reserved slot {id:?}"
);
*slot = Slot::Node(node.into());
}
pub(crate) fn all_filled(&self) -> bool {
self.slots.iter().all(|slot| matches!(slot, Slot::Node(_)))
}
pub(crate) fn node_count(&self) -> usize {
self.slots.len()
}
pub(crate) fn ty(&self, node_id: NodeId) -> &stmt::Type {
self[node_id].ty()
}
}
impl ops::Index<NodeId> for Store {
type Output = Node;
#[track_caller]
fn index(&self, index: NodeId) -> &Self::Output {
match &self.slots[index] {
Slot::Node(node) => node,
Slot::Reserved => panic!("reserved MIR slot {index:?} read before fill"),
}
}
}
impl ops::IndexMut<NodeId> for Store {
#[track_caller]
fn index_mut(&mut self, index: NodeId) -> &mut Self::Output {
match &mut self.slots[index] {
Slot::Node(node) => node,
Slot::Reserved => panic!("reserved MIR slot {index:?} read before fill"),
}
}
}
impl ops::Index<&NodeId> for Store {
type Output = Node;
#[track_caller]
fn index(&self, index: &NodeId) -> &Self::Output {
self.index(*index)
}
}
impl ops::IndexMut<&NodeId> for Store {
#[track_caller]
fn index_mut(&mut self, index: &NodeId) -> &mut Self::Output {
self.index_mut(*index)
}
}