Same as [`try_nonrecursive_dft`], but allows changes to be made to the graph.
(
graph: &mut Graph,
root: NodeId,
at_enter: &mut AtEnter,
at_exit: &mut AtExit,
)
| 83 | |
| 84 | /// Same as [`try_nonrecursive_dft`], but allows changes to be made to the graph. |
| 85 | pub fn try_nonrecursive_dft_mut<Graph, NodeId, AtEnter, AtExit, E>( |
| 86 | graph: &mut Graph, |
| 87 | root: NodeId, |
| 88 | at_enter: &mut AtEnter, |
| 89 | at_exit: &mut AtExit, |
| 90 | ) -> Result<(), E> |
| 91 | where |
| 92 | NodeId: std::cmp::Ord + Clone, |
| 93 | AtEnter: FnMut(&mut Graph, &NodeId) -> Result<Vec<NodeId>, E>, |
| 94 | AtExit: FnMut(&mut Graph, &NodeId) -> Result<(), E>, |
| 95 | { |
| 96 | // Code in this method is identical to the code in `nonrecursive_dft`. |
| 97 | let mut entered = Vec::new(); |
| 98 | let mut exited = BTreeSet::new(); |
| 99 | |
| 100 | let children = at_enter(graph, &root)?; |
| 101 | entered_node(&mut entered, root, children); |
| 102 | while !entered.is_empty() { |
| 103 | if let Some(to_enter) = find_next_child_to_enter(&mut entered, &exited) { |
| 104 | let children = at_enter(graph, &to_enter)?; |
| 105 | entered_node(&mut entered, to_enter, children); |
| 106 | } else { |
| 107 | let (to_exit, _) = entered.pop().unwrap(); |
| 108 | at_exit(graph, &to_exit)?; |
| 109 | exited.insert(to_exit); |
| 110 | } |
| 111 | } |
| 112 | Ok(()) |
| 113 | } |
| 114 | |
| 115 | /// A non-recursive implementation of an infallible depth-first traversal |
| 116 | /// starting from `root`. |
nothing calls this directly
no test coverage detected