use std::{
collections::{BTreeMap, HashMap},
hash::Hash,
marker::PhantomData,
ops::{Index, IndexMut},
};
use crate::{
graph::{GraphBase, NodeMapImpl},
index::{Idx, vec::IndexVec},
};
pub struct NodeMap<G: GraphBase, Value> {
marker: PhantomData<G>,
imp: G::NodeMapImpl<Value>,
}
impl<G: GraphBase, Value> NodeMap<G, Value> {
pub fn new(graph: G) -> NodeMap<G, Value>
where
Value: Default,
{
NodeMap::new_with(graph, |_| Value::default())
}
pub fn new_with(graph: G, f: impl FnMut(G::Node) -> Value) -> NodeMap<G, Value> {
let mut this = NodeMap {
marker: PhantomData,
imp: G::NodeMapImpl::default(),
};
this.clear_with(graph, f);
this
}
#[inline(always)]
pub fn clear(&mut self, graph: G)
where
Value: Default,
{
graph.clear_nodemap(&mut self.imp, |_| Value::default());
}
#[inline(always)]
pub fn clear_with(&mut self, graph: G, f: impl FnMut(G::Node) -> Value) {
graph.clear_nodemap(&mut self.imp, f);
}
}
impl<G: GraphBase, Value> Index<G::Node> for NodeMap<G, Value> {
type Output = Value;
fn index(&self, index: G::Node) -> &Value {
self.imp.nodemap_get(index)
}
}
impl<G: GraphBase, Value> IndexMut<G::Node> for NodeMap<G, Value> {
fn index_mut(&mut self, index: G::Node) -> &mut Value {
self.imp.nodemap_get_mut(index)
}
}
impl<Node: Idx, Value> NodeMapImpl<Node> for IndexVec<Node, Value> {
type Value = Value;
fn nodemap_get(&self, node: Node) -> &Value {
&self[node]
}
fn nodemap_get_mut(&mut self, node: Node) -> &mut Value {
&mut self[node]
}
}
impl<Node: Copy + Eq + Hash, Value> NodeMapImpl<Node> for HashMap<Node, Value> {
type Value = Value;
fn nodemap_get(&self, node: Node) -> &Self::Value {
self.get(&node).unwrap()
}
fn nodemap_get_mut(&mut self, node: Node) -> &mut Self::Value {
self.get_mut(&node).unwrap()
}
}
impl<Node: Copy + Ord, Value> NodeMapImpl<Node> for BTreeMap<Node, Value> {
type Value = Value;
fn nodemap_get(&self, node: Node) -> &Self::Value {
self.get(&node).unwrap()
}
fn nodemap_get_mut(&mut self, node: Node) -> &mut Self::Value {
self.get_mut(&node).unwrap()
}
}