about summary refs log tree commit diff
path: root/src/librustc_data_structures/graph/iterate
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2019-06-11 16:29:27 -0400
committerNiko Matsakis <niko@alum.mit.edu>2019-07-02 12:15:20 -0400
commit7fd0db7dd319cfb73664c8a068474dc8759ebabf (patch)
tree2f9d9d37bea1229cecb25c4a04ba855ca795a8c2 /src/librustc_data_structures/graph/iterate
parent4c91bb9571ffbc7ddad52cc98552f5b19b0d44d7 (diff)
add a `depth_first_search` helper function
Diffstat (limited to 'src/librustc_data_structures/graph/iterate')
-rw-r--r--src/librustc_data_structures/graph/iterate/mod.rs36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/src/librustc_data_structures/graph/iterate/mod.rs
index c09364b0a53..5612778ce07 100644
--- a/src/librustc_data_structures/graph/iterate/mod.rs
+++ b/src/librustc_data_structures/graph/iterate/mod.rs
@@ -1,5 +1,6 @@
 use super::super::indexed_vec::IndexVec;
-use super::{DirectedGraph, WithSuccessors, WithNumNodes};
+use super::{DirectedGraph, WithNumNodes, WithSuccessors};
+use crate::bit_set::BitSet;
 
 #[cfg(test)]
 mod test;
@@ -51,3 +52,36 @@ pub fn reverse_post_order<G: DirectedGraph + WithSuccessors + WithNumNodes>(
     vec.reverse();
     vec
 }
+
+/// A "depth-first search" iterator for a directed graph.
+pub struct DepthFirstSearch<'graph, G>
+where
+    G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
+{
+    graph: &'graph G,
+    stack: Vec<G::Node>,
+    visited: BitSet<G::Node>,
+}
+
+impl<G> DepthFirstSearch<'graph, G>
+where
+    G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
+{
+    pub fn new(graph: &'graph G, start_node: G::Node) -> Self {
+        Self { graph, stack: vec![start_node], visited: BitSet::new_empty(graph.num_nodes()) }
+    }
+}
+
+impl<G> Iterator for DepthFirstSearch<'_, G>
+where
+    G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
+{
+    type Item = G::Node;
+
+    fn next(&mut self) -> Option<G::Node> {
+        let DepthFirstSearch { stack, visited, graph } = self;
+        let n = stack.pop()?;
+        stack.extend(graph.successors(n).filter(|&m| visited.insert(m)));
+        Some(n)
+    }
+}