use std::ops::{Index, IndexMut}; use crate::traits::GraphTopology; pub struct VertexMap { inner: EntityMap, } impl VertexMap { pub fn new(default: T, to_index: fn(V) -> usize, capacity: usize) -> Self { Self { inner: EntityMap::new(default, to_index, capacity), } } // Reads beyond len() are valid and return the default value. pub fn len(&self) -> usize { self.inner.len() } pub fn sync>(&mut self, graph: &G) { self.inner.resize(graph.vertex_capacity()); } } impl Index for VertexMap { type Output = T; fn index(&self, v: V) -> &T { &self.inner[v] } } impl IndexMut for VertexMap { fn index_mut(&mut self, v: V) -> &mut T { &mut self.inner[v] } } pub struct EdgeMap { inner: EntityMap, } impl EdgeMap { pub fn new(default: T, to_index: fn(E) -> usize, capacity: usize) -> Self { Self { inner: EntityMap::new(default, to_index, capacity), } } // Reads beyond len() are valid and return the default value. pub fn len(&self) -> usize { self.inner.len() } pub fn sync>(&mut self, graph: &G) { self.inner.resize(graph.edge_capacity()); } } impl Index for EdgeMap { type Output = T; fn index(&self, e: E) -> &T { &self.inner[e] } } impl IndexMut for EdgeMap { fn index_mut(&mut self, e: E) -> &mut T { &mut self.inner[e] } } struct EntityMap { data: Vec, default: T, to_index: fn(E) -> usize, } impl EntityMap { pub fn new(default: T, to_index: fn(E) -> usize, capacity: usize) -> Self { Self { data: vec![default.clone(); capacity], default, to_index, } } pub fn len(&self) -> usize { self.data.len() } pub fn resize(&mut self, capacity: usize) { if capacity > self.data.len() { self.data.resize(capacity, self.default.clone()); } } } impl Index for EntityMap { type Output = T; fn index(&self, e: E) -> &T { let i = (self.to_index)(e); if i < self.data.len() { &self.data[i] } else { &self.default } } } impl IndexMut for EntityMap { fn index_mut(&mut self, e: E) -> &mut T { let i = (self.to_index)(e); if i >= self.data.len() { self.data.resize(i + 1, self.default.clone()); } &mut self.data[i] } } #[cfg(test)] mod append_graph_vertex_map_tests { use crate::models::append_graph::AppendGraph; use crate::traits::GraphTopology; crate::vertex_map_tests!(AppendGraph); } #[cfg(test)] mod append_graph_edge_map_tests { use crate::models::append_graph::AppendGraph; use crate::traits::GraphTopology; crate::edge_map_tests!(AppendGraph); } #[cfg(test)] mod graph_vertex_map_tests { use crate::models::graph::Graph; use crate::traits::{GraphTopology, GraphTopologyDeletion}; crate::vertex_map_tests!(Graph); crate::vertex_map_deletion_tests!(Graph); } #[cfg(test)] mod graph_edge_map_tests { use crate::models::graph::Graph; use crate::traits::{GraphTopology, GraphTopologyDeletion}; crate::edge_map_tests!(Graph); crate::edge_map_deletion_tests!(Graph); }