1
Fork 0

Add wrapper type ReversedGraph for swapping successors/predecessors

This commit is contained in:
Zalathar 2025-01-12 12:40:03 +11:00
parent a48e7b0057
commit 1a23a6fd8b
2 changed files with 43 additions and 0 deletions

View file

@ -4,6 +4,7 @@ pub mod dominators;
pub mod implementation;
pub mod iterate;
mod reference;
pub mod reversed;
pub mod scc;
pub mod vec_graph;

View file

@ -0,0 +1,42 @@
use crate::graph::{DirectedGraph, Predecessors, Successors};
/// View that reverses the direction of edges in its underlying graph, so that
/// successors become predecessors and vice-versa.
///
/// Because of `impl<G: Graph> Graph for &G`, the underlying graph can be
/// wrapped by-reference instead of by-value if desired.
#[derive(Clone, Copy, Debug)]
pub struct ReversedGraph<G> {
pub inner: G,
}
impl<G> ReversedGraph<G> {
pub fn new(inner: G) -> Self {
Self { inner }
}
}
impl<G: DirectedGraph> DirectedGraph for ReversedGraph<G> {
type Node = G::Node;
fn num_nodes(&self) -> usize {
self.inner.num_nodes()
}
}
// Implementing `StartNode` is not possible in general, because the start node
// of an underlying graph is instead an _end_ node in the reversed graph.
// But would be possible to define another wrapper type that adds an explicit
// start node to its underlying graph, if desired.
impl<G: Predecessors> Successors for ReversedGraph<G> {
fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
self.inner.predecessors(node)
}
}
impl<G: Successors> Predecessors for ReversedGraph<G> {
fn predecessors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
self.inner.successors(node)
}
}