Add From and FromGraph implementations for Graph and AppendGraph
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
//! Concrete graph topology models.
|
//! Concrete graph topology models.
|
||||||
|
|
||||||
|
use crate::maps::ElementMap;
|
||||||
|
use crate::traits::{GraphTopology, GraphTopologyAddition};
|
||||||
|
|
||||||
pub mod append_graph;
|
pub mod append_graph;
|
||||||
pub mod frozen_graph;
|
pub mod frozen_graph;
|
||||||
pub mod graph;
|
pub mod graph;
|
||||||
@@ -11,3 +14,35 @@ pub use frozen_graph::{
|
|||||||
FrozenGraph, FrozenGraphEdgeMap, FrozenGraphIncidence, FrozenGraphVertexMap,
|
FrozenGraph, FrozenGraphEdgeMap, FrozenGraphIncidence, FrozenGraphVertexMap,
|
||||||
};
|
};
|
||||||
pub use graph::{Graph, GraphEdgeMap, GraphIncidence, GraphVertexMap};
|
pub use graph::{Graph, GraphEdgeMap, GraphIncidence, GraphVertexMap};
|
||||||
|
|
||||||
|
/// Builds a new graph isomorphic to `source`.
|
||||||
|
///
|
||||||
|
/// The resulting graph type `G` must implement [`GraphTopologyAddition`] which is used to add
|
||||||
|
/// vertices and edges. `on_edge` is called for each edge in `source` together with the
|
||||||
|
/// corresponding new edge of the new graph, which callers can use to construct an edge mapping.
|
||||||
|
///
|
||||||
|
/// Used by the [`GraphTopologyAddition`] models' `From<&H>` and [`FromGraph`] implementations.
|
||||||
|
///
|
||||||
|
/// [`FromGraph`]: crate::traits::FromGraph
|
||||||
|
pub(crate) fn build_from_topology<G: GraphTopologyAddition, H: GraphTopology>(
|
||||||
|
source: &H,
|
||||||
|
vertex_default: G::Vertex,
|
||||||
|
mut on_edge: impl FnMut(H::Edge, G::Edge),
|
||||||
|
) -> (G, ElementMap<H::Vertex, G::Vertex>) {
|
||||||
|
let mut result = G::default();
|
||||||
|
result.reserve_vertices(source.vertex_count());
|
||||||
|
result.reserve_edges(source.edge_count());
|
||||||
|
|
||||||
|
let mut vertex_map = source.vertex_map(vertex_default);
|
||||||
|
for v in source.vertices() {
|
||||||
|
vertex_map[v] = result.add_vertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
for e in source.edges() {
|
||||||
|
let (u, v) = source.incident_vertices(e);
|
||||||
|
let new_edge = result.add_edge(vertex_map[u], vertex_map[v]);
|
||||||
|
on_edge(e, new_edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
(result, vertex_map)
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
use crate::maps::ElementMap;
|
use crate::maps::ElementMap;
|
||||||
use crate::traits::{GraphTopology, GraphTopologyAddition, Incidence, IncidenceCursor};
|
use crate::models;
|
||||||
|
use crate::traits::{FromGraph, GraphTopology, GraphTopologyAddition, Incidence, IncidenceCursor};
|
||||||
|
|
||||||
/// An opaque handle identifying a vertex in an [`AppendGraph`].
|
/// An opaque handle identifying a vertex in an [`AppendGraph`].
|
||||||
///
|
///
|
||||||
@@ -259,14 +260,38 @@ impl GraphTopologyAddition for AppendGraph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<H: GraphTopology> From<&H> for AppendGraph {
|
||||||
|
fn from(source: &H) -> Self {
|
||||||
|
models::build_from_topology::<Self, _>(source, Vertex(usize::MAX), |_, _| {}).0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromGraph for AppendGraph {
|
||||||
|
fn from_graph<H: GraphTopology>(
|
||||||
|
source: &H,
|
||||||
|
) -> (
|
||||||
|
Self,
|
||||||
|
ElementMap<H::Vertex, Vertex>,
|
||||||
|
ElementMap<H::Edge, Edge>,
|
||||||
|
) {
|
||||||
|
let mut edge_map = source.edge_map(Edge(NonZeroUsize::MAX));
|
||||||
|
let (result, vertex_map) =
|
||||||
|
models::build_from_topology(source, Vertex(usize::MAX), |e, new_e| edge_map[e] = new_e);
|
||||||
|
(result, vertex_map, edge_map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod trait_tests {
|
mod trait_tests {
|
||||||
use super::AppendGraph;
|
use super::AppendGraph;
|
||||||
|
use crate::models::Graph;
|
||||||
|
|
||||||
crate::graph_topology_tests!(AppendGraph);
|
crate::graph_topology_tests!(AppendGraph);
|
||||||
crate::graph_topology_addition_tests!(AppendGraph);
|
crate::graph_topology_addition_tests!(AppendGraph);
|
||||||
crate::graph_topology_clone_tests!(AppendGraph);
|
crate::graph_topology_clone_tests!(AppendGraph);
|
||||||
crate::graph_topology_addition_clone_tests!(AppendGraph);
|
crate::graph_topology_addition_clone_tests!(AppendGraph);
|
||||||
|
crate::graph_topology_from_graph_tests!(AppendGraph, Graph);
|
||||||
|
crate::graph_topology_addition_from_graph_tests!(AppendGraph, Graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
+34
-1
@@ -4,8 +4,10 @@ use std::num::NonZeroUsize;
|
|||||||
use typed_generational_arena::{Arena, Index};
|
use typed_generational_arena::{Arena, Index};
|
||||||
|
|
||||||
use crate::maps::ElementMap;
|
use crate::maps::ElementMap;
|
||||||
|
use crate::models;
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
GraphTopology, GraphTopologyAddition, GraphTopologyDeletion, Incidence, IncidenceCursor,
|
FromGraph, GraphTopology, GraphTopologyAddition, GraphTopologyDeletion, Incidence,
|
||||||
|
IncidenceCursor,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An opaque handle identifying a vertex in a [`Graph`].
|
/// An opaque handle identifying a vertex in a [`Graph`].
|
||||||
@@ -398,9 +400,38 @@ impl GraphTopologyDeletion for Graph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<H: GraphTopology> From<&H> for Graph {
|
||||||
|
fn from(source: &H) -> Self {
|
||||||
|
models::build_from_topology::<Self, _>(
|
||||||
|
source,
|
||||||
|
Vertex::new(usize::MAX, usize::MAX),
|
||||||
|
|_, _| {},
|
||||||
|
)
|
||||||
|
.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromGraph for Graph {
|
||||||
|
fn from_graph<H: GraphTopology>(
|
||||||
|
source: &H,
|
||||||
|
) -> (
|
||||||
|
Self,
|
||||||
|
ElementMap<H::Vertex, Vertex>,
|
||||||
|
ElementMap<H::Edge, Edge>,
|
||||||
|
) {
|
||||||
|
let mut edge_map = source.edge_map(Edge::new(usize::MAX, usize::MAX));
|
||||||
|
let (result, vertex_map) =
|
||||||
|
models::build_from_topology(source, Vertex::new(usize::MAX, usize::MAX), |e, new_e| {
|
||||||
|
edge_map[e] = new_e
|
||||||
|
});
|
||||||
|
(result, vertex_map, edge_map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod trait_tests {
|
mod trait_tests {
|
||||||
use super::Graph;
|
use super::Graph;
|
||||||
|
use crate::models::AppendGraph;
|
||||||
|
|
||||||
crate::graph_topology_tests!(Graph);
|
crate::graph_topology_tests!(Graph);
|
||||||
crate::graph_topology_addition_tests!(Graph);
|
crate::graph_topology_addition_tests!(Graph);
|
||||||
@@ -408,6 +439,8 @@ mod trait_tests {
|
|||||||
crate::graph_topology_addition_deletion_tests!(Graph);
|
crate::graph_topology_addition_deletion_tests!(Graph);
|
||||||
crate::graph_topology_clone_tests!(Graph);
|
crate::graph_topology_clone_tests!(Graph);
|
||||||
crate::graph_topology_addition_clone_tests!(Graph);
|
crate::graph_topology_addition_clone_tests!(Graph);
|
||||||
|
crate::graph_topology_from_graph_tests!(Graph, AppendGraph);
|
||||||
|
crate::graph_topology_addition_from_graph_tests!(Graph, AppendGraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user