Add GraphTopologyAddition trait from GraphTopology

Move capacity and add methods from GraphTopology trait to new GraphTopologyAddition trait
This commit is contained in:
2026-08-06 14:17:21 +02:00
parent 2851cf60fd
commit 10d0c382cc
10 changed files with 75 additions and 63 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
use crate::traits::GraphTopology; use crate::traits::{GraphTopology, GraphTopologyAddition};
pub fn petersen<G>( pub fn petersen<G>(
graph: &mut G, graph: &mut G,
@@ -7,7 +7,7 @@ pub fn petersen<G>(
[<G as GraphTopology>::Edge; 15], [<G as GraphTopology>::Edge; 15],
) )
where where
G: GraphTopology, G: GraphTopologyAddition,
{ {
const N: usize = 5; const N: usize = 5;
const K: usize = 2; const K: usize = 2;
+3 -1
View File
@@ -136,7 +136,9 @@ pub mod traits;
/// Convenience re-exports of graph topology traits for common use. /// Convenience re-exports of graph topology traits for common use.
pub mod prelude { pub mod prelude {
pub use crate::traits::{GraphTopology, GraphTopologyDeletion, Incidence, IncidenceCursor}; pub use crate::traits::{
GraphTopology, GraphTopologyAddition, GraphTopologyDeletion, Incidence, IncidenceCursor,
};
} }
mod testing; mod testing;
+11 -9
View File
@@ -1,7 +1,7 @@
//! [`AppendGraph`], an undirected graph topology supporting addition only. //! [`AppendGraph`], an undirected graph topology supporting addition only.
use crate::maps::EntityMap; use crate::maps::EntityMap;
use crate::traits::{GraphTopology, Incidence, IncidenceCursor}; use crate::traits::{GraphTopology, GraphTopologyAddition, Incidence, IncidenceCursor};
/// An opaque handle identifying a vertex in an [`AppendGraph`]. /// An opaque handle identifying a vertex in an [`AppendGraph`].
/// ///
@@ -147,10 +147,6 @@ impl GraphTopology for AppendGraph {
self.vertices.len() self.vertices.len()
} }
fn vertex_capacity(&self) -> usize {
self.vertices.capacity()
}
fn vertex_map<T: Clone>(&self, default: T) -> EntityMap<Self::Vertex, T> { fn vertex_map<T: Clone>(&self, default: T) -> EntityMap<Self::Vertex, T> {
EntityMap::new(default, |v| v.0, self.vertex_capacity()) EntityMap::new(default, |v| v.0, self.vertex_capacity())
} }
@@ -159,10 +155,6 @@ impl GraphTopology for AppendGraph {
self.incidences.len() / 2 self.incidences.len() / 2
} }
fn edge_capacity(&self) -> usize {
self.incidences.capacity() / 2
}
fn edge_map<T: Clone>(&self, default: T) -> EntityMap<Self::Edge, T> { fn edge_map<T: Clone>(&self, default: T) -> EntityMap<Self::Edge, T> {
EntityMap::new(default, |e| e.0 / 2, self.edge_capacity()) EntityMap::new(default, |e| e.0 / 2, self.edge_capacity())
} }
@@ -209,6 +201,16 @@ impl GraphTopology for AppendGraph {
incidence: self.vertices[v.0].first_incidence, incidence: self.vertices[v.0].first_incidence,
} }
} }
}
impl GraphTopologyAddition for AppendGraph {
fn vertex_capacity(&self) -> usize {
self.vertices.capacity()
}
fn edge_capacity(&self) -> usize {
self.incidences.capacity() / 2
}
fn add_vertex(&mut self) -> Self::Vertex { fn add_vertex(&mut self) -> Self::Vertex {
self.vertices.push(VertexIncidenceHeader { self.vertices.push(VertexIncidenceHeader {
+13 -9
View File
@@ -3,7 +3,9 @@
use typed_generational_arena::{Arena, Index}; use typed_generational_arena::{Arena, Index};
use crate::maps::EntityMap; use crate::maps::EntityMap;
use crate::traits::{GraphTopology, GraphTopologyDeletion, Incidence, IncidenceCursor}; use crate::traits::{
GraphTopology, GraphTopologyAddition, GraphTopologyDeletion, Incidence, IncidenceCursor,
};
/// An opaque handle identifying a vertex in a [`Graph`]. /// An opaque handle identifying a vertex in a [`Graph`].
/// ///
@@ -239,10 +241,6 @@ impl GraphTopology for Graph {
self.vertices.len() self.vertices.len()
} }
fn vertex_capacity(&self) -> usize {
self.vertices.capacity()
}
fn vertex_map<T: Clone>(&self, default: T) -> EntityMap<Self::Vertex, T> { fn vertex_map<T: Clone>(&self, default: T) -> EntityMap<Self::Vertex, T> {
EntityMap::new(default, |v| v.arr_idx(), self.vertex_capacity()) EntityMap::new(default, |v| v.arr_idx(), self.vertex_capacity())
} }
@@ -251,10 +249,6 @@ impl GraphTopology for Graph {
self.incidences.len() / 2 self.incidences.len() / 2
} }
fn edge_capacity(&self) -> usize {
self.incidences.capacity() / 2
}
fn edge_map<T: Clone>(&self, default: T) -> EntityMap<Self::Edge, T> { fn edge_map<T: Clone>(&self, default: T) -> EntityMap<Self::Edge, T> {
EntityMap::new(default, |e| e.arr_idx() / 2, self.edge_capacity()) EntityMap::new(default, |e| e.arr_idx() / 2, self.edge_capacity())
} }
@@ -312,6 +306,16 @@ impl GraphTopology for Graph {
incidence: self.vertices[v].first_incidence, incidence: self.vertices[v].first_incidence,
} }
} }
}
impl GraphTopologyAddition for Graph {
fn vertex_capacity(&self) -> usize {
self.vertices.capacity()
}
fn edge_capacity(&self) -> usize {
self.incidences.capacity() / 2
}
fn add_vertex(&mut self) -> Self::Vertex { fn add_vertex(&mut self) -> Self::Vertex {
self.vertices.insert(VertexIncidenceHeader { self.vertices.insert(VertexIncidenceHeader {
+4 -4
View File
@@ -4,7 +4,7 @@ macro_rules! bfs_tests {
($T:ty) => { ($T:ty) => {
#[test] #[test]
fn bfs_single_vertex() { fn bfs_single_vertex() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
let result = $crate::algorithms::bfs(&graph, v); let result = $crate::algorithms::bfs(&graph, v);
@@ -54,7 +54,7 @@ macro_rules! bfs_tests {
#[test] #[test]
fn bfs_distances_single_vertex() { fn bfs_distances_single_vertex() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
let distances = $crate::algorithms::bfs_distances(&graph, v); let distances = $crate::algorithms::bfs_distances(&graph, v);
@@ -91,7 +91,7 @@ macro_rules! bfs_tests {
#[test] #[test]
fn bfs_find_source() { fn bfs_find_source() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
assert_eq!( assert_eq!(
@@ -139,7 +139,7 @@ macro_rules! bfs_tests {
#[test] #[test]
fn bfs_find_where_source_matches() { fn bfs_find_where_source_matches() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
assert_eq!( assert_eq!(
+7 -7
View File
@@ -4,7 +4,7 @@ macro_rules! dfs_tests {
($T:ty) => { ($T:ty) => {
#[test] #[test]
fn dfs_single_vertex() { fn dfs_single_vertex() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
let result = $crate::algorithms::dfs(&graph, v); let result = $crate::algorithms::dfs(&graph, v);
@@ -49,7 +49,7 @@ macro_rules! dfs_tests {
#[test] #[test]
fn dfs_visited_single_vertex() { fn dfs_visited_single_vertex() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
let visited = $crate::algorithms::dfs_visited(&graph, v); let visited = $crate::algorithms::dfs_visited(&graph, v);
@@ -78,7 +78,7 @@ macro_rules! dfs_tests {
#[test] #[test]
fn dfs_find_source() { fn dfs_find_source() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
assert!( assert!(
@@ -111,7 +111,7 @@ macro_rules! dfs_tests {
#[test] #[test]
fn dfs_find_where_source_matches() { fn dfs_find_where_source_matches() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
assert_eq!( assert_eq!(
@@ -205,7 +205,7 @@ macro_rules! dfs_tests {
#[test] #[test]
fn dfs_find_path_source_equals_target() { fn dfs_find_path_source_equals_target() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
assert_eq!( assert_eq!(
@@ -227,7 +227,7 @@ macro_rules! dfs_tests {
#[test] #[test]
fn dfs_find_path_adjacent() { fn dfs_find_path_adjacent() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v1 = graph.add_vertex(); let v1 = graph.add_vertex();
let v2 = graph.add_vertex(); let v2 = graph.add_vertex();
@@ -255,7 +255,7 @@ macro_rules! dfs_tests {
#[test] #[test]
fn dfs_find_path_where_source_matches() { fn dfs_find_path_where_source_matches() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
assert_eq!( assert_eq!(
+4 -4
View File
@@ -4,7 +4,7 @@ macro_rules! dijkstra_tests {
($T:ty) => { ($T:ty) => {
#[test] #[test]
fn dijkstra_single_vertex() { fn dijkstra_single_vertex() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
let result = $crate::algorithms::dijkstra(&graph, v, |_| { let result = $crate::algorithms::dijkstra(&graph, v, |_| {
@@ -25,7 +25,7 @@ macro_rules! dijkstra_tests {
#[test] #[test]
fn dijkstra_zero_weight_loop() { fn dijkstra_zero_weight_loop() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition};
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let vertices: [<$T as $crate::traits::GraphTopology>::Vertex; 3] = let vertices: [<$T as $crate::traits::GraphTopology>::Vertex; 3] =
core::array::from_fn(|_| graph.add_vertex()); core::array::from_fn(|_| graph.add_vertex());
@@ -71,7 +71,7 @@ macro_rules! dijkstra_tests {
#[test] #[test]
fn dijkstra_unweighted_single_vertex() { fn dijkstra_unweighted_single_vertex() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
let result = $crate::algorithms::dijkstra_unweighted(&graph, v); let result = $crate::algorithms::dijkstra_unweighted(&graph, v);
@@ -95,7 +95,7 @@ macro_rules! dijkstra_tests {
#[test] #[test]
fn dijkstra_distances_unweighted_single_vertex() { fn dijkstra_distances_unweighted_single_vertex() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
let distances = $crate::algorithms::dijkstra_distances_unweighted(&graph, v); let distances = $crate::algorithms::dijkstra_distances_unweighted(&graph, v);
+6 -6
View File
@@ -15,7 +15,7 @@ macro_rules! graph_topology_test_fixtures {
<$T as $crate::traits::GraphTopology>::Edge, <$T as $crate::traits::GraphTopology>::Edge,
>>; 10], >>; 10],
) { ) {
use $crate::traits::{GraphTopology, Incidence}; use $crate::traits::{GraphTopology, GraphTopologyAddition, Incidence};
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let vertices: [<$T as $crate::traits::GraphTopology>::Vertex; 10] = let vertices: [<$T as $crate::traits::GraphTopology>::Vertex; 10] =
core::array::from_fn(|_| graph.add_vertex()); core::array::from_fn(|_| graph.add_vertex());
@@ -96,7 +96,7 @@ macro_rules! graph_topology_test_fixtures {
#[allow(dead_code)] #[allow(dead_code)]
fn make_test_graph_disconnected() fn make_test_graph_disconnected()
-> ($T, [<$T as $crate::traits::GraphTopology>::Vertex; 3]) { -> ($T, [<$T as $crate::traits::GraphTopology>::Vertex; 3]) {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let vertices: [<$T as $crate::traits::GraphTopology>::Vertex; 3] = let vertices: [<$T as $crate::traits::GraphTopology>::Vertex; 3] =
core::array::from_fn(|_| graph.add_vertex()); core::array::from_fn(|_| graph.add_vertex());
@@ -112,7 +112,7 @@ macro_rules! graph_topology_tests {
($T:ty) => { ($T:ty) => {
#[test] #[test]
fn add_vertex() { fn add_vertex() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
assert_ne!(graph.add_vertex(), v, "unexpected duplicate vertex"); assert_ne!(graph.add_vertex(), v, "unexpected duplicate vertex");
@@ -147,7 +147,7 @@ macro_rules! graph_topology_tests {
#[test] #[test]
fn add_edge() { fn add_edge() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v1 = graph.add_vertex(); let v1 = graph.add_vertex();
let v2 = graph.add_vertex(); let v2 = graph.add_vertex();
@@ -974,7 +974,7 @@ macro_rules! graph_topology_deletion_tests {
#[test] #[test]
fn delete_vertex_invalid_index() { fn delete_vertex_invalid_index() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
use $crate::traits::GraphTopologyDeletion; use $crate::traits::GraphTopologyDeletion;
let mut graph = Graph::new(); let mut graph = Graph::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
@@ -1169,7 +1169,7 @@ macro_rules! graph_topology_deletion_tests {
#[test] #[test]
fn delete_edge_invalid_index() { fn delete_edge_invalid_index() {
use $crate::traits::GraphTopology; use $crate::traits::GraphTopologyAddition;
use $crate::traits::GraphTopologyDeletion; use $crate::traits::GraphTopologyDeletion;
let mut graph = Graph::new(); let mut graph = Graph::new();
let v1 = graph.add_vertex(); let v1 = graph.add_vertex();
+8 -10
View File
@@ -4,7 +4,7 @@ macro_rules! entity_map_tests {
($T:ty) => { ($T:ty) => {
#[test] #[test]
fn initial_values_are_default() { fn initial_values_are_default() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition};
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v1 = graph.add_vertex(); let v1 = graph.add_vertex();
let v2 = graph.add_vertex(); let v2 = graph.add_vertex();
@@ -15,7 +15,7 @@ macro_rules! entity_map_tests {
#[test] #[test]
fn write_and_read() { fn write_and_read() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition};
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v1 = graph.add_vertex(); let v1 = graph.add_vertex();
let v2 = graph.add_vertex(); let v2 = graph.add_vertex();
@@ -27,7 +27,7 @@ macro_rules! entity_map_tests {
#[test] #[test]
fn lazy_growth_on_read() { fn lazy_growth_on_read() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition};
let mut graph = <$T>::new(); let mut graph = <$T>::new();
graph.add_vertex(); graph.add_vertex();
let map = graph.vertex_map(99); let map = graph.vertex_map(99);
@@ -37,7 +37,7 @@ macro_rules! entity_map_tests {
#[test] #[test]
fn lazy_growth_on_write() { fn lazy_growth_on_write() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition};
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v1 = graph.add_vertex(); let v1 = graph.add_vertex();
let mut map = graph.vertex_map(0); let mut map = graph.vertex_map(0);
@@ -49,7 +49,7 @@ macro_rules! entity_map_tests {
#[test] #[test]
fn expand_to_new_vertices() { fn expand_to_new_vertices() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition};
let mut graph = <$T>::new(); let mut graph = <$T>::new();
graph.add_vertex(); graph.add_vertex();
let mut map = graph.vertex_map(42); let mut map = graph.vertex_map(42);
@@ -67,7 +67,7 @@ macro_rules! entity_map_tests {
#[test] #[test]
fn expand_does_not_overwrite_existing_values() { fn expand_does_not_overwrite_existing_values() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition};
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v = graph.add_vertex(); let v = graph.add_vertex();
let mut map = graph.vertex_map(0); let mut map = graph.vertex_map(0);
@@ -85,8 +85,7 @@ macro_rules! entity_map_deletion_tests {
($T:ty) => { ($T:ty) => {
#[test] #[test]
fn surviving_vertex_readable_after_delete() { fn surviving_vertex_readable_after_delete() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition, GraphTopologyDeletion};
use $crate::traits::GraphTopologyDeletion;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
let v1 = graph.add_vertex(); let v1 = graph.add_vertex();
let v2 = graph.add_vertex(); let v2 = graph.add_vertex();
@@ -99,8 +98,7 @@ macro_rules! entity_map_deletion_tests {
#[test] #[test]
fn reused_slot_returns_old_value() { fn reused_slot_returns_old_value() {
use $crate::traits::GraphTopology; use $crate::traits::{GraphTopology, GraphTopologyAddition, GraphTopologyDeletion};
use $crate::traits::GraphTopologyDeletion;
let mut graph = <$T>::new(); let mut graph = <$T>::new();
graph.add_vertex(); graph.add_vertex();
let v1 = graph.add_vertex(); let v1 = graph.add_vertex();
+17 -11
View File
@@ -2,13 +2,11 @@
use crate::maps::EntityMap; use crate::maps::EntityMap;
// TODO: Add functions to reserve memory for vertices and edges.
// TODO: Split out GraphTopologyAddition trait.
/// A trait representing an undirected graph topology. /// A trait representing an undirected graph topology.
/// ///
/// An undirected graph is a set of vertices and undirected edges, where each edge connects either /// An undirected graph is a set of vertices and undirected edges, where each edge connects either
/// exactly two vertices or one vertex with itself (loop edge). This trait provides methods for /// exactly two vertices or one vertex with itself (loop edge). This trait provides methods for
/// querying a graph topology, iterating over vertices and edges, and adding new vertices and edges. /// querying a graph topology, and iterating over vertices and edges.
/// ///
/// # Vertices and edges /// # Vertices and edges
/// ///
@@ -20,9 +18,10 @@ use crate::maps::EntityMap;
/// Methods accepting vertices or edges as parameters panic if the handle was invalidated by a /// Methods accepting vertices or edges as parameters panic if the handle was invalidated by a
/// deletion, and return incorrect results if the handle was not produced by this graph instance. /// deletion, and return incorrect results if the handle was not produced by this graph instance.
/// ///
/// # Deletion /// # Addition and deletion
/// ///
/// This trait covers graph construction and querying only. To delete vertices and edges, see /// This trait covers graph querying only. To construct a graph incrementally by adding vertices and
/// edges, see [`GraphTopologyAddition`]. To delete vertices and edges, see
/// [`GraphTopologyDeletion`]. /// [`GraphTopologyDeletion`].
/// ///
/// [`Edge`]: GraphTopology::Edge /// [`Edge`]: GraphTopology::Edge
@@ -45,9 +44,6 @@ pub trait GraphTopology {
/// Returns the number of vertices in the graph. /// Returns the number of vertices in the graph.
fn vertex_count(&self) -> usize; fn vertex_count(&self) -> usize;
/// Returns the total number of vertices the graph can hold without reallocating.
fn vertex_capacity(&self) -> usize;
/// Creates and returns an [`EntityMap`] for the vertices with every slot initialised to /// Creates and returns an [`EntityMap`] for the vertices with every slot initialised to
/// `default`. /// `default`.
/// ///
@@ -74,9 +70,6 @@ pub trait GraphTopology {
/// Returns the number of edges in the graph. /// Returns the number of edges in the graph.
fn edge_count(&self) -> usize; fn edge_count(&self) -> usize;
/// Returns the total number of edges the graph can hold without reallocating.
fn edge_capacity(&self) -> usize;
/// Creates and returns an [`EntityMap`] for the edges with every slot initialised to `default`. /// Creates and returns an [`EntityMap`] for the edges with every slot initialised to `default`.
/// ///
/// # Examples /// # Examples
@@ -179,6 +172,19 @@ pub trait GraphTopology {
/// ///
/// Panics if `v` is not a valid vertex of this graph. /// Panics if `v` is not a valid vertex of this graph.
fn incidence_cursor(&self, v: Self::Vertex) -> Self::IncidenceCursor; fn incidence_cursor(&self, v: Self::Vertex) -> Self::IncidenceCursor;
}
// TODO: Add functions to reserve memory for vertices and edges.
/// A trait that adds construction operations to an undirected graph topology.
///
/// This trait provides methods for addition of vertices and edges, and capacity management in an
/// undirected graph.
pub trait GraphTopologyAddition: GraphTopology {
/// Returns the total number of vertices the graph can hold without reallocating.
fn vertex_capacity(&self) -> usize;
/// Returns the total number of edges the graph can hold without reallocating.
fn edge_capacity(&self) -> usize;
/// Adds a new isolated vertex and returns its handle. /// Adds a new isolated vertex and returns its handle.
fn add_vertex(&mut self) -> Self::Vertex; fn add_vertex(&mut self) -> Self::Vertex;