mod diff;
mod scc;
mod visit;
pub use self::{
diff::{CfgDiff, CfgUpdate, CfgUpdateKind, GraphDiff},
scc::StronglyConnectedComponents,
visit::{DefaultGraphVisitor, GraphVisitor, LazyDfsVisitor, PostOrderIter, PreOrderIter},
};
pub trait Graph {
type Node: Clone;
type ChildIter: ExactSizeIterator<Item = Self::Node>;
type Edge;
type ChildEdgeIter: ExactSizeIterator<Item = Self::Edge>;
#[inline]
fn is_empty(&self) -> bool {
self.size() == 0
}
fn size(&self) -> usize;
fn entry_node(&self) -> Self::Node;
fn children(parent: Self::Node) -> Self::ChildIter;
fn children_edges(parent: Self::Node) -> Self::ChildEdgeIter;
fn edge_dest(edge: Self::Edge) -> Self::Node;
}
impl<G: Graph> Graph for &G {
type ChildEdgeIter = <G as Graph>::ChildEdgeIter;
type ChildIter = <G as Graph>::ChildIter;
type Edge = <G as Graph>::Edge;
type Node = <G as Graph>::Node;
fn is_empty(&self) -> bool {
(**self).is_empty()
}
fn size(&self) -> usize {
(**self).size()
}
fn entry_node(&self) -> Self::Node {
(**self).entry_node()
}
fn children(parent: Self::Node) -> Self::ChildIter {
<G as Graph>::children(parent)
}
fn children_edges(parent: Self::Node) -> Self::ChildEdgeIter {
<G as Graph>::children_edges(parent)
}
fn edge_dest(edge: Self::Edge) -> Self::Node {
<G as Graph>::edge_dest(edge)
}
}
pub trait InvertibleGraph: Graph {
type Inverse: Graph;
type InvertibleChildIter: ExactSizeIterator<Item = Self::Node>;
type InvertibleChildEdgeIter: ExactSizeIterator<Item = Self::Edge>;
fn inverse_children(parent: Self::Node) -> Self::InvertibleChildIter;
fn inverse_children_edges(parent: Self::Node) -> Self::InvertibleChildEdgeIter;
fn inverse(self) -> Self::Inverse;
}
pub struct Inverse<G: Graph> {
graph: G,
}
impl<G: Graph> Inverse<G> {
#[inline]
pub fn new(graph: G) -> Self {
Self { graph }
}
}
impl<G: InvertibleGraph> Graph for Inverse<G> {
type ChildEdgeIter = InverseChildEdgeIter<<G as InvertibleGraph>::InvertibleChildEdgeIter>;
type ChildIter = InverseChildIter<<G as InvertibleGraph>::InvertibleChildIter>;
type Edge = <G as Graph>::Edge;
type Node = <G as Graph>::Node;
fn is_empty(&self) -> bool {
self.graph.is_empty()
}
fn size(&self) -> usize {
self.graph.size()
}
fn entry_node(&self) -> Self::Node {
self.graph.entry_node()
}
fn children(parent: Self::Node) -> Self::ChildIter {
InverseChildIter::new(<G as InvertibleGraph>::inverse_children(parent))
}
fn children_edges(parent: Self::Node) -> Self::ChildEdgeIter {
InverseChildEdgeIter::new(<G as InvertibleGraph>::inverse_children_edges(parent))
}
fn edge_dest(edge: Self::Edge) -> Self::Node {
<G as Graph>::edge_dest(edge)
}
}
impl<G: InvertibleGraph> InvertibleGraph for Inverse<G> {
type Inverse = G;
type InvertibleChildEdgeIter = <G as Graph>::ChildEdgeIter;
type InvertibleChildIter = <G as Graph>::ChildIter;
fn inverse_children(parent: Self::Node) -> Self::InvertibleChildIter {
<G as Graph>::children(parent)
}
fn inverse_children_edges(parent: Self::Node) -> Self::InvertibleChildEdgeIter {
<G as Graph>::children_edges(parent)
}
fn inverse(self) -> Self::Inverse {
self.graph
}
}
#[doc(hidden)]
pub struct InverseChildIter<I> {
iter: I,
}
impl<I: ExactSizeIterator> InverseChildIter<I> {
pub fn new(iter: I) -> Self {
Self { iter }
}
}
impl<I: ExactSizeIterator> ExactSizeIterator for InverseChildIter<I> {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
#[inline]
fn is_empty(&self) -> bool {
self.iter.is_empty()
}
}
impl<I: Iterator> Iterator for InverseChildIter<I> {
type Item = <I as Iterator>::Item;
default fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}
#[doc(hidden)]
pub struct InverseChildEdgeIter<I> {
iter: I,
}
impl<I: ExactSizeIterator> InverseChildEdgeIter<I> {
pub fn new(iter: I) -> Self {
Self { iter }
}
}
impl<I: ExactSizeIterator> ExactSizeIterator for InverseChildEdgeIter<I> {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
#[inline]
fn is_empty(&self) -> bool {
self.iter.is_empty()
}
}
impl<I: Iterator> Iterator for InverseChildEdgeIter<I> {
type Item = <I as Iterator>::Item;
default fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}