1mod diff;
2mod scc;
3mod visit;
4
5pub use self::{
6 diff::{CfgDiff, CfgUpdate, CfgUpdateKind, GraphDiff},
7 scc::StronglyConnectedComponents,
8 visit::{DefaultGraphVisitor, GraphVisitor, LazyDfsVisitor, PostOrderIter, PreOrderIter},
9};
10
11pub trait Graph {
22 type Node: Clone;
26 type ChildIter: ExactSizeIterator<Item = Self::Node>;
28 type Edge;
32 type ChildEdgeIter: ExactSizeIterator<Item = Self::Edge>;
34
35 #[inline]
37 fn is_empty(&self) -> bool {
38 self.size() == 0
39 }
40 fn size(&self) -> usize;
42 fn entry_node(&self) -> Self::Node;
48 fn children(parent: Self::Node) -> Self::ChildIter;
50 fn children_edges(parent: Self::Node) -> Self::ChildEdgeIter;
52 fn edge_dest(edge: Self::Edge) -> Self::Node;
54}
55
56impl<G: Graph> Graph for &G {
57 type ChildEdgeIter = <G as Graph>::ChildEdgeIter;
58 type ChildIter = <G as Graph>::ChildIter;
59 type Edge = <G as Graph>::Edge;
60 type Node = <G as Graph>::Node;
61
62 fn is_empty(&self) -> bool {
63 (**self).is_empty()
64 }
65
66 fn size(&self) -> usize {
67 (**self).size()
68 }
69
70 fn entry_node(&self) -> Self::Node {
71 (**self).entry_node()
72 }
73
74 fn children(parent: Self::Node) -> Self::ChildIter {
75 <G as Graph>::children(parent)
76 }
77
78 fn children_edges(parent: Self::Node) -> Self::ChildEdgeIter {
79 <G as Graph>::children_edges(parent)
80 }
81
82 fn edge_dest(edge: Self::Edge) -> Self::Node {
83 <G as Graph>::edge_dest(edge)
84 }
85}
86
87pub trait InvertibleGraph: Graph {
95 type Inverse: Graph;
103 type InvertibleChildIter: ExactSizeIterator<Item = Self::Node>;
106 type InvertibleChildEdgeIter: ExactSizeIterator<Item = Self::Edge>;
109
110 fn inverse_children(parent: Self::Node) -> Self::InvertibleChildIter;
116 fn inverse_children_edges(parent: Self::Node) -> Self::InvertibleChildEdgeIter;
118 fn inverse(self) -> Self::Inverse;
120}
121
122pub struct Inverse<G: Graph> {
129 graph: G,
130}
131
132impl<G: Graph> Inverse<G> {
133 #[inline]
135 pub fn new(graph: G) -> Self {
136 Self { graph }
137 }
138}
139
140impl<G: InvertibleGraph> Graph for Inverse<G> {
141 type ChildEdgeIter = InverseChildEdgeIter<<G as InvertibleGraph>::InvertibleChildEdgeIter>;
142 type ChildIter = InverseChildIter<<G as InvertibleGraph>::InvertibleChildIter>;
143 type Edge = <G as Graph>::Edge;
144 type Node = <G as Graph>::Node;
145
146 fn is_empty(&self) -> bool {
147 self.graph.is_empty()
148 }
149
150 fn size(&self) -> usize {
151 self.graph.size()
152 }
153
154 fn entry_node(&self) -> Self::Node {
155 self.graph.entry_node()
156 }
157
158 fn children(parent: Self::Node) -> Self::ChildIter {
159 InverseChildIter::new(<G as InvertibleGraph>::inverse_children(parent))
160 }
161
162 fn children_edges(parent: Self::Node) -> Self::ChildEdgeIter {
163 InverseChildEdgeIter::new(<G as InvertibleGraph>::inverse_children_edges(parent))
164 }
165
166 fn edge_dest(edge: Self::Edge) -> Self::Node {
167 <G as Graph>::edge_dest(edge)
168 }
169}
170
171impl<G: InvertibleGraph> InvertibleGraph for Inverse<G> {
172 type Inverse = G;
173 type InvertibleChildEdgeIter = <G as Graph>::ChildEdgeIter;
174 type InvertibleChildIter = <G as Graph>::ChildIter;
175
176 fn inverse_children(parent: Self::Node) -> Self::InvertibleChildIter {
177 <G as Graph>::children(parent)
178 }
179
180 fn inverse_children_edges(parent: Self::Node) -> Self::InvertibleChildEdgeIter {
181 <G as Graph>::children_edges(parent)
182 }
183
184 fn inverse(self) -> Self::Inverse {
185 self.graph
186 }
187}
188
189#[doc(hidden)]
191pub struct InverseChildIter<I> {
192 iter: I,
193}
194
195impl<I: ExactSizeIterator> InverseChildIter<I> {
196 pub fn new(iter: I) -> Self {
197 Self { iter }
198 }
199}
200impl<I: ExactSizeIterator> ExactSizeIterator for InverseChildIter<I> {
201 #[inline]
202 fn len(&self) -> usize {
203 self.iter.len()
204 }
205
206 #[inline]
207 fn is_empty(&self) -> bool {
208 self.iter.is_empty()
209 }
210}
211impl<I: Iterator> Iterator for InverseChildIter<I> {
212 type Item = <I as Iterator>::Item;
213
214 default fn next(&mut self) -> Option<Self::Item> {
215 self.iter.next()
216 }
217}
218
219#[doc(hidden)]
222pub struct InverseChildEdgeIter<I> {
223 iter: I,
224}
225impl<I: ExactSizeIterator> InverseChildEdgeIter<I> {
226 pub fn new(iter: I) -> Self {
227 Self { iter }
228 }
229}
230impl<I: ExactSizeIterator> ExactSizeIterator for InverseChildEdgeIter<I> {
231 #[inline]
232 fn len(&self) -> usize {
233 self.iter.len()
234 }
235
236 #[inline]
237 fn is_empty(&self) -> bool {
238 self.iter.is_empty()
239 }
240}
241impl<I: Iterator> Iterator for InverseChildEdgeIter<I> {
242 type Item = <I as Iterator>::Item;
243
244 default fn next(&mut self) -> Option<Self::Item> {
245 self.iter.next()
246 }
247}