summaryrefslogtreecommitdiffstats
path: root/vendor/petgraph/src/visit
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/petgraph/src/visit')
-rw-r--r--vendor/petgraph/src/visit/dfsvisit.rs314
-rw-r--r--vendor/petgraph/src/visit/filter.rs505
-rw-r--r--vendor/petgraph/src/visit/macros.rs135
-rw-r--r--vendor/petgraph/src/visit/mod.rs755
-rw-r--r--vendor/petgraph/src/visit/reversed.rs170
-rw-r--r--vendor/petgraph/src/visit/traversal.rs519
6 files changed, 2398 insertions, 0 deletions
diff --git a/vendor/petgraph/src/visit/dfsvisit.rs b/vendor/petgraph/src/visit/dfsvisit.rs
new file mode 100644
index 000000000..b14dad5dd
--- /dev/null
+++ b/vendor/petgraph/src/visit/dfsvisit.rs
@@ -0,0 +1,314 @@
+use crate::visit::IntoNeighbors;
+use crate::visit::{VisitMap, Visitable};
+
+/// Strictly monotonically increasing event time for a depth first search.
+#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Default, Hash)]
+pub struct Time(pub usize);
+
+/// A depth first search (DFS) visitor event.
+#[derive(Copy, Clone, Debug)]
+pub enum DfsEvent<N> {
+ Discover(N, Time),
+ /// An edge of the tree formed by the traversal.
+ TreeEdge(N, N),
+ /// An edge to an already visited node.
+ BackEdge(N, N),
+ /// A cross or forward edge.
+ ///
+ /// For an edge *(u, v)*, if the discover time of *v* is greater than *u*,
+ /// then it is a forward edge, else a cross edge.
+ CrossForwardEdge(N, N),
+ /// All edges from a node have been reported.
+ Finish(N, Time),
+}
+
+/// Return if the expression is a break value, execute the provided statement
+/// if it is a prune value.
+macro_rules! try_control {
+ ($e:expr, $p:stmt) => {
+ try_control!($e, $p, ());
+ };
+ ($e:expr, $p:stmt, $q:stmt) => {
+ match $e {
+ x => {
+ if x.should_break() {
+ return x;
+ } else if x.should_prune() {
+ $p
+ } else {
+ $q
+ }
+ }
+ }
+ };
+}
+
+/// Control flow for `depth_first_search` callbacks.
+#[derive(Copy, Clone, Debug)]
+pub enum Control<B> {
+ /// Continue the DFS traversal as normal.
+ Continue,
+ /// Prune the current node from the DFS traversal. No more edges from this
+ /// node will be reported to the callback. A `DfsEvent::Finish` for this
+ /// node will still be reported. This can be returned in response to any
+ /// `DfsEvent`, except `Finish`, which will panic.
+ Prune,
+ /// Stop the DFS traversal and return the provided value.
+ Break(B),
+}
+
+impl<B> Control<B> {
+ pub fn breaking() -> Control<()> {
+ Control::Break(())
+ }
+ /// Get the value in `Control::Break(_)`, if present.
+ pub fn break_value(self) -> Option<B> {
+ match self {
+ Control::Continue | Control::Prune => None,
+ Control::Break(b) => Some(b),
+ }
+ }
+}
+
+/// Control flow for callbacks.
+///
+/// The empty return value `()` is equivalent to continue.
+pub trait ControlFlow {
+ fn continuing() -> Self;
+ fn should_break(&self) -> bool;
+ fn should_prune(&self) -> bool;
+}
+
+impl ControlFlow for () {
+ fn continuing() {}
+ #[inline]
+ fn should_break(&self) -> bool {
+ false
+ }
+ #[inline]
+ fn should_prune(&self) -> bool {
+ false
+ }
+}
+
+impl<B> ControlFlow for Control<B> {
+ fn continuing() -> Self {
+ Control::Continue
+ }
+ fn should_break(&self) -> bool {
+ if let Control::Break(_) = *self {
+ true
+ } else {
+ false
+ }
+ }
+ fn should_prune(&self) -> bool {
+ match *self {
+ Control::Prune => true,
+ Control::Continue | Control::Break(_) => false,
+ }
+ }
+}
+
+impl<C: ControlFlow, E> ControlFlow for Result<C, E> {
+ fn continuing() -> Self {
+ Ok(C::continuing())
+ }
+ fn should_break(&self) -> bool {
+ if let Ok(ref c) = *self {
+ c.should_break()
+ } else {
+ true
+ }
+ }
+ fn should_prune(&self) -> bool {
+ if let Ok(ref c) = *self {
+ c.should_prune()
+ } else {
+ false
+ }
+ }
+}
+
+/// The default is `Continue`.
+impl<B> Default for Control<B> {
+ fn default() -> Self {
+ Control::Continue
+ }
+}
+
+/// A recursive depth first search.
+///
+/// Starting points are the nodes in the iterator `starts` (specify just one
+/// start vertex *x* by using `Some(x)`).
+///
+/// The traversal emits discovery and finish events for each reachable vertex,
+/// and edge classification of each reachable edge. `visitor` is called for each
+/// event, see [`DfsEvent`][de] for possible values.
+///
+/// The return value should implement the trait `ControlFlow`, and can be used to change
+/// the control flow of the search.
+///
+/// `Control` Implements `ControlFlow` such that `Control::Continue` resumes the search.
+/// `Control::Break` will stop the visit early, returning the contained value.
+/// `Control::Prune` will stop traversing any additional edges from the current
+/// node and proceed immediately to the `Finish` event.
+///
+/// There are implementations of `ControlFlow` for `()`, and `Result<C, E>` where
+/// `C: ControlFlow`. The implementation for `()` will continue until finished.
+/// For `Result`, upon encountering an `E` it will break, otherwise acting the same as `C`.
+///
+/// ***Panics** if you attempt to prune a node from its `Finish` event.
+///
+/// [de]: enum.DfsEvent.html
+///
+/// # Example returning `Control`.
+///
+/// Find a path from vertex 0 to 5, and exit the visit as soon as we reach
+/// the goal vertex.
+///
+/// ```
+/// use petgraph::prelude::*;
+/// use petgraph::graph::node_index as n;
+/// use petgraph::visit::depth_first_search;
+/// use petgraph::visit::{DfsEvent, Control};
+///
+/// let gr: Graph<(), ()> = Graph::from_edges(&[
+/// (0, 1), (0, 2), (0, 3),
+/// (1, 3),
+/// (2, 3), (2, 4),
+/// (4, 0), (4, 5),
+/// ]);
+///
+/// // record each predecessor, mapping node → node
+/// let mut predecessor = vec![NodeIndex::end(); gr.node_count()];
+/// let start = n(0);
+/// let goal = n(5);
+/// depth_first_search(&gr, Some(start), |event| {
+/// if let DfsEvent::TreeEdge(u, v) = event {
+/// predecessor[v.index()] = u;
+/// if v == goal {
+/// return Control::Break(v);
+/// }
+/// }
+/// Control::Continue
+/// });
+///
+/// let mut next = goal;
+/// let mut path = vec![next];
+/// while next != start {
+/// let pred = predecessor[next.index()];
+/// path.push(pred);
+/// next = pred;
+/// }
+/// path.reverse();
+/// assert_eq!(&path, &[n(0), n(2), n(4), n(5)]);
+/// ```
+///
+/// # Example returning a `Result`.
+/// ```
+/// use petgraph::graph::node_index as n;
+/// use petgraph::prelude::*;
+/// use petgraph::visit::depth_first_search;
+/// use petgraph::visit::{DfsEvent, Time};
+///
+/// let gr: Graph<(), ()> = Graph::from_edges(&[(0, 1), (1, 2), (1, 1), (2, 1)]);
+/// let start = n(0);
+/// let mut back_edges = 0;
+/// let mut discover_time = 0;
+/// // Stop the search, the first time a BackEdge is encountered.
+/// let result = depth_first_search(&gr, Some(start), |event| {
+/// match event {
+/// // In the cases where Ok(()) is returned,
+/// // Result falls back to the implementation of Control on the value ().
+/// // In the case of (), this is to always return Control::Continue.
+/// // continuing the search.
+/// DfsEvent::Discover(_, Time(t)) => {
+/// discover_time = t;
+/// Ok(())
+/// }
+/// DfsEvent::BackEdge(_, _) => {
+/// back_edges += 1;
+/// // the implementation of ControlFlow for Result,
+/// // treats this Err value as Continue::Break
+/// Err(event)
+/// }
+/// _ => Ok(()),
+/// }
+/// });
+///
+/// // Even though the graph has more than one cycle,
+/// // The number of back_edges visited by the search should always be 1.
+/// assert_eq!(back_edges, 1);
+/// println!("discover time:{:?}", discover_time);
+/// println!("number of backedges encountered: {}", back_edges);
+/// println!("back edge: {:?}", result);
+/// ```
+pub fn depth_first_search<G, I, F, C>(graph: G, starts: I, mut visitor: F) -> C
+where
+ G: IntoNeighbors + Visitable,
+ I: IntoIterator<Item = G::NodeId>,
+ F: FnMut(DfsEvent<G::NodeId>) -> C,
+ C: ControlFlow,
+{
+ let time = &mut Time(0);
+ let discovered = &mut graph.visit_map();
+ let finished = &mut graph.visit_map();
+
+ for start in starts {
+ try_control!(
+ dfs_visitor(graph, start, &mut visitor, discovered, finished, time),
+ unreachable!()
+ );
+ }
+ C::continuing()
+}
+
+fn dfs_visitor<G, F, C>(
+ graph: G,
+ u: G::NodeId,
+ visitor: &mut F,
+ discovered: &mut G::Map,
+ finished: &mut G::Map,
+ time: &mut Time,
+) -> C
+where
+ G: IntoNeighbors + Visitable,
+ F: FnMut(DfsEvent<G::NodeId>) -> C,
+ C: ControlFlow,
+{
+ if !discovered.visit(u) {
+ return C::continuing();
+ }
+
+ try_control!(
+ visitor(DfsEvent::Discover(u, time_post_inc(time))),
+ {},
+ for v in graph.neighbors(u) {
+ if !discovered.is_visited(&v) {
+ try_control!(visitor(DfsEvent::TreeEdge(u, v)), continue);
+ try_control!(
+ dfs_visitor(graph, v, visitor, discovered, finished, time),
+ unreachable!()
+ );
+ } else if !finished.is_visited(&v) {
+ try_control!(visitor(DfsEvent::BackEdge(u, v)), continue);
+ } else {
+ try_control!(visitor(DfsEvent::CrossForwardEdge(u, v)), continue);
+ }
+ }
+ );
+ let first_finish = finished.visit(u);
+ debug_assert!(first_finish);
+ try_control!(
+ visitor(DfsEvent::Finish(u, time_post_inc(time))),
+ panic!("Pruning on the `DfsEvent::Finish` is not supported!")
+ );
+ C::continuing()
+}
+
+fn time_post_inc(x: &mut Time) -> Time {
+ let v = *x;
+ x.0 += 1;
+ v
+}
diff --git a/vendor/petgraph/src/visit/filter.rs b/vendor/petgraph/src/visit/filter.rs
new file mode 100644
index 000000000..110ebea25
--- /dev/null
+++ b/vendor/petgraph/src/visit/filter.rs
@@ -0,0 +1,505 @@
+use crate::prelude::*;
+
+use fixedbitset::FixedBitSet;
+use std::collections::HashSet;
+use std::marker::PhantomData;
+
+use crate::data::DataMap;
+use crate::visit::{Data, NodeCompactIndexable, NodeCount};
+use crate::visit::{
+ GraphBase, GraphProp, IntoEdgeReferences, IntoEdges, IntoEdgesDirected, IntoNeighbors,
+ IntoNeighborsDirected, IntoNodeIdentifiers, IntoNodeReferences, NodeIndexable, NodeRef,
+ VisitMap, Visitable,
+};
+
+/// A graph filter for nodes.
+pub trait FilterNode<N> {
+ /// Return true to have the node be part of the graph
+ fn include_node(&self, node: N) -> bool;
+}
+
+impl<F, N> FilterNode<N> for F
+where
+ F: Fn(N) -> bool,
+{
+ fn include_node(&self, n: N) -> bool {
+ (*self)(n)
+ }
+}
+
+/// This filter includes the nodes that are contained in the set.
+impl<N> FilterNode<N> for FixedBitSet
+where
+ FixedBitSet: VisitMap<N>,
+{
+ fn include_node(&self, n: N) -> bool {
+ self.is_visited(&n)
+ }
+}
+
+/// This filter includes the nodes that are contained in the set.
+impl<N, S> FilterNode<N> for HashSet<N, S>
+where
+ HashSet<N, S>: VisitMap<N>,
+{
+ fn include_node(&self, n: N) -> bool {
+ self.is_visited(&n)
+ }
+}
+
+// Can't express these as a generic impl over all references since that would conflict with the
+// impl for Fn.
+impl<N> FilterNode<N> for &FixedBitSet
+where
+ FixedBitSet: VisitMap<N>,
+{
+ fn include_node(&self, n: N) -> bool {
+ self.is_visited(&n)
+ }
+}
+
+impl<N, S> FilterNode<N> for &HashSet<N, S>
+where
+ HashSet<N, S>: VisitMap<N>,
+{
+ fn include_node(&self, n: N) -> bool {
+ self.is_visited(&n)
+ }
+}
+
+/// A node-filtering graph adaptor.
+#[derive(Copy, Clone, Debug)]
+pub struct NodeFiltered<G, F>(pub G, pub F);
+
+impl<F, G> NodeFiltered<G, F>
+where
+ G: GraphBase,
+ F: Fn(G::NodeId) -> bool,
+{
+ /// Create an `NodeFiltered` adaptor from the closure `filter`.
+ pub fn from_fn(graph: G, filter: F) -> Self {
+ NodeFiltered(graph, filter)
+ }
+}
+
+impl<G, F> GraphBase for NodeFiltered<G, F>
+where
+ G: GraphBase,
+{
+ type NodeId = G::NodeId;
+ type EdgeId = G::EdgeId;
+}
+
+impl<'a, G, F> IntoNeighbors for &'a NodeFiltered<G, F>
+where
+ G: IntoNeighbors,
+ F: FilterNode<G::NodeId>,
+{
+ type Neighbors = NodeFilteredNeighbors<'a, G::Neighbors, F>;
+ fn neighbors(self, n: G::NodeId) -> Self::Neighbors {
+ NodeFilteredNeighbors {
+ include_source: self.1.include_node(n),
+ iter: self.0.neighbors(n),
+ f: &self.1,
+ }
+ }
+}
+
+/// A filtered neighbors iterator.
+pub struct NodeFilteredNeighbors<'a, I, F: 'a> {
+ include_source: bool,
+ iter: I,
+ f: &'a F,
+}
+
+impl<'a, I, F> Iterator for NodeFilteredNeighbors<'a, I, F>
+where
+ I: Iterator,
+ I::Item: Copy,
+ F: FilterNode<I::Item>,
+{
+ type Item = I::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ let f = self.f;
+ if !self.include_source {
+ None
+ } else {
+ self.iter.find(move |&target| f.include_node(target))
+ }
+ }
+}
+
+impl<'a, G, F> IntoNeighborsDirected for &'a NodeFiltered<G, F>
+where
+ G: IntoNeighborsDirected,
+ F: FilterNode<G::NodeId>,
+{
+ type NeighborsDirected = NodeFilteredNeighbors<'a, G::NeighborsDirected, F>;
+ fn neighbors_directed(self, n: G::NodeId, dir: Direction) -> Self::NeighborsDirected {
+ NodeFilteredNeighbors {
+ include_source: self.1.include_node(n),
+ iter: self.0.neighbors_directed(n, dir),
+ f: &self.1,
+ }
+ }
+}
+
+impl<'a, G, F> IntoNodeIdentifiers for &'a NodeFiltered<G, F>
+where
+ G: IntoNodeIdentifiers,
+ F: FilterNode<G::NodeId>,
+{
+ type NodeIdentifiers = NodeFilteredNeighbors<'a, G::NodeIdentifiers, F>;
+ fn node_identifiers(self) -> Self::NodeIdentifiers {
+ NodeFilteredNeighbors {
+ include_source: true,
+ iter: self.0.node_identifiers(),
+ f: &self.1,
+ }
+ }
+}
+
+impl<'a, G, F> IntoNodeReferences for &'a NodeFiltered<G, F>
+where
+ G: IntoNodeReferences,
+ F: FilterNode<G::NodeId>,
+{
+ type NodeRef = G::NodeRef;
+ type NodeReferences = NodeFilteredNodes<'a, G::NodeReferences, F>;
+ fn node_references(self) -> Self::NodeReferences {
+ NodeFilteredNodes {
+ include_source: true,
+ iter: self.0.node_references(),
+ f: &self.1,
+ }
+ }
+}
+
+/// A filtered node references iterator.
+pub struct NodeFilteredNodes<'a, I, F: 'a> {
+ include_source: bool,
+ iter: I,
+ f: &'a F,
+}
+
+impl<'a, I, F> Iterator for NodeFilteredNodes<'a, I, F>
+where
+ I: Iterator,
+ I::Item: Copy + NodeRef,
+ F: FilterNode<<I::Item as NodeRef>::NodeId>,
+{
+ type Item = I::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ let f = self.f;
+ if !self.include_source {
+ None
+ } else {
+ self.iter.find(move |&target| f.include_node(target.id()))
+ }
+ }
+}
+
+impl<'a, G, F> IntoEdgeReferences for &'a NodeFiltered<G, F>
+where
+ G: IntoEdgeReferences,
+ F: FilterNode<G::NodeId>,
+{
+ type EdgeRef = G::EdgeRef;
+ type EdgeReferences = NodeFilteredEdgeReferences<'a, G, G::EdgeReferences, F>;
+ fn edge_references(self) -> Self::EdgeReferences {
+ NodeFilteredEdgeReferences {
+ graph: PhantomData,
+ iter: self.0.edge_references(),
+ f: &self.1,
+ }
+ }
+}
+
+/// A filtered edges iterator.
+pub struct NodeFilteredEdgeReferences<'a, G, I, F: 'a> {
+ graph: PhantomData<G>,
+ iter: I,
+ f: &'a F,
+}
+
+impl<'a, G, I, F> Iterator for NodeFilteredEdgeReferences<'a, G, I, F>
+where
+ F: FilterNode<G::NodeId>,
+ G: IntoEdgeReferences,
+ I: Iterator<Item = G::EdgeRef>,
+{
+ type Item = I::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ let f = self.f;
+ self.iter
+ .find(move |&edge| f.include_node(edge.source()) && f.include_node(edge.target()))
+ }
+}
+
+impl<'a, G, F> IntoEdges for &'a NodeFiltered<G, F>
+where
+ G: IntoEdges,
+ F: FilterNode<G::NodeId>,
+{
+ type Edges = NodeFilteredEdges<'a, G, G::Edges, F>;
+ fn edges(self, a: G::NodeId) -> Self::Edges {
+ NodeFilteredEdges {
+ graph: PhantomData,
+ include_source: self.1.include_node(a),
+ iter: self.0.edges(a),
+ f: &self.1,
+ }
+ }
+}
+
+/// A filtered edges iterator.
+pub struct NodeFilteredEdges<'a, G, I, F: 'a> {
+ graph: PhantomData<G>,
+ include_source: bool,
+ iter: I,
+ f: &'a F,
+}
+
+impl<'a, G, I, F> Iterator for NodeFilteredEdges<'a, G, I, F>
+where
+ F: FilterNode<G::NodeId>,
+ G: IntoEdges,
+ I: Iterator<Item = G::EdgeRef>,
+{
+ type Item = I::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ if !self.include_source {
+ None
+ } else {
+ let f = self.f;
+ self.iter.find(move |&edge| f.include_node(edge.target()))
+ }
+ }
+}
+
+impl<G, F> DataMap for NodeFiltered<G, F>
+where
+ G: DataMap,
+ F: FilterNode<G::NodeId>,
+{
+ fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
+ if self.1.include_node(id) {
+ self.0.node_weight(id)
+ } else {
+ None
+ }
+ }
+
+ fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
+ self.0.edge_weight(id)
+ }
+}
+
+macro_rules! access0 {
+ ($e:expr) => {
+ $e.0
+ };
+}
+
+Data! {delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
+NodeIndexable! {delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
+GraphProp! {delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
+Visitable! {delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
+
+/// A graph filter for edges
+pub trait FilterEdge<Edge> {
+ /// Return true to have the edge be part of the graph
+ fn include_edge(&self, edge: Edge) -> bool;
+}
+
+impl<F, N> FilterEdge<N> for F
+where
+ F: Fn(N) -> bool,
+{
+ fn include_edge(&self, n: N) -> bool {
+ (*self)(n)
+ }
+}
+
+/// An edge-filtering graph adaptor.
+///
+/// The adaptor may filter out edges. The filter implements the trait
+/// `FilterEdge`. Closures of type `Fn(G::EdgeRef) -> bool` already
+/// implement this trait.
+///
+/// The filter may use edge source, target, id, and weight to select whether to
+/// include the edge or not.
+#[derive(Copy, Clone, Debug)]
+pub struct EdgeFiltered<G, F>(pub G, pub F);
+
+impl<F, G> EdgeFiltered<G, F>
+where
+ G: IntoEdgeReferences,
+ F: Fn(G::EdgeRef) -> bool,
+{
+ /// Create an `EdgeFiltered` adaptor from the closure `filter`.
+ pub fn from_fn(graph: G, filter: F) -> Self {
+ EdgeFiltered(graph, filter)
+ }
+}
+
+impl<G, F> GraphBase for EdgeFiltered<G, F>
+where
+ G: GraphBase,
+{
+ type NodeId = G::NodeId;
+ type EdgeId = G::EdgeId;
+}
+
+impl<'a, G, F> IntoNeighbors for &'a EdgeFiltered<G, F>
+where
+ G: IntoEdges,
+ F: FilterEdge<G::EdgeRef>,
+{
+ type Neighbors = EdgeFilteredNeighbors<'a, G, F>;
+ fn neighbors(self, n: G::NodeId) -> Self::Neighbors {
+ EdgeFilteredNeighbors {
+ iter: self.0.edges(n),
+ f: &self.1,
+ }
+ }
+}
+
+impl<'a, G, F> IntoNeighborsDirected for &'a EdgeFiltered<G, F>
+where
+ G: IntoEdgesDirected,
+ F: FilterEdge<G::EdgeRef>,
+{
+ type NeighborsDirected = EdgeFilteredNeighborsDirected<'a, G, F>;
+ fn neighbors_directed(self, n: G::NodeId, dir: Direction) -> Self::NeighborsDirected {
+ EdgeFilteredNeighborsDirected {
+ iter: self.0.edges_directed(n, dir),
+ f: &self.1,
+ from: n,
+ }
+ }
+}
+
+/// A filtered neighbors iterator.
+pub struct EdgeFilteredNeighbors<'a, G, F: 'a>
+where
+ G: IntoEdges,
+{
+ iter: G::Edges,
+ f: &'a F,
+}
+
+impl<'a, G, F> Iterator for EdgeFilteredNeighbors<'a, G, F>
+where
+ F: FilterEdge<G::EdgeRef>,
+ G: IntoEdges,
+{
+ type Item = G::NodeId;
+ fn next(&mut self) -> Option<Self::Item> {
+ let f = self.f;
+ (&mut self.iter)
+ .filter_map(move |edge| {
+ if f.include_edge(edge) {
+ Some(edge.target())
+ } else {
+ None
+ }
+ })
+ .next()
+ }
+}
+
+impl<'a, G, F> IntoEdgeReferences for &'a EdgeFiltered<G, F>
+where
+ G: IntoEdgeReferences,
+ F: FilterEdge<G::EdgeRef>,
+{
+ type EdgeRef = G::EdgeRef;
+ type EdgeReferences = EdgeFilteredEdges<'a, G, G::EdgeReferences, F>;
+ fn edge_references(self) -> Self::EdgeReferences {
+ EdgeFilteredEdges {
+ graph: PhantomData,
+ iter: self.0.edge_references(),
+ f: &self.1,
+ }
+ }
+}
+
+impl<'a, G, F> IntoEdges for &'a EdgeFiltered<G, F>
+where
+ G: IntoEdges,
+ F: FilterEdge<G::EdgeRef>,
+{
+ type Edges = EdgeFilteredEdges<'a, G, G::Edges, F>;
+ fn edges(self, n: G::NodeId) -> Self::Edges {
+ EdgeFilteredEdges {
+ graph: PhantomData,
+ iter: self.0.edges(n),
+ f: &self.1,
+ }
+ }
+}
+
+/// A filtered edges iterator.
+pub struct EdgeFilteredEdges<'a, G, I, F: 'a> {
+ graph: PhantomData<G>,
+ iter: I,
+ f: &'a F,
+}
+
+impl<'a, G, I, F> Iterator for EdgeFilteredEdges<'a, G, I, F>
+where
+ F: FilterEdge<G::EdgeRef>,
+ G: IntoEdgeReferences,
+ I: Iterator<Item = G::EdgeRef>,
+{
+ type Item = I::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ let f = self.f;
+ self.iter.find(move |&edge| f.include_edge(edge))
+ }
+}
+
+/// A filtered neighbors-directed iterator.
+pub struct EdgeFilteredNeighborsDirected<'a, G, F: 'a>
+where
+ G: IntoEdgesDirected,
+{
+ iter: G::EdgesDirected,
+ f: &'a F,
+ from: G::NodeId,
+}
+
+impl<'a, G, F> Iterator for EdgeFilteredNeighborsDirected<'a, G, F>
+where
+ F: FilterEdge<G::EdgeRef>,
+ G: IntoEdgesDirected,
+{
+ type Item = G::NodeId;
+ fn next(&mut self) -> Option<Self::Item> {
+ let f = self.f;
+ let from = self.from;
+ (&mut self.iter)
+ .filter_map(move |edge| {
+ if f.include_edge(edge) {
+ if edge.source() != from {
+ Some(edge.source())
+ } else {
+ Some(edge.target()) // includes case where from == source == target
+ }
+ } else {
+ None
+ }
+ })
+ .next()
+ }
+}
+
+Data! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
+GraphProp! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
+IntoNodeIdentifiers! {delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
+IntoNodeReferences! {delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
+NodeCompactIndexable! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
+NodeCount! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
+NodeIndexable! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
+Visitable! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
diff --git a/vendor/petgraph/src/visit/macros.rs b/vendor/petgraph/src/visit/macros.rs
new file mode 100644
index 000000000..1b36030de
--- /dev/null
+++ b/vendor/petgraph/src/visit/macros.rs
@@ -0,0 +1,135 @@
+/// Define a trait as usual, and a macro that can be used to instantiate
+/// implementations of it.
+///
+/// There *must* be section markers in the trait definition:
+/// @section type for associated types
+/// @section self for methods
+/// @section nodelegate for arbitrary tail that is not forwarded.
+macro_rules! trait_template {
+ ($(#[$doc:meta])* pub trait $name:ident $($methods:tt)*) => {
+ macro_rules! $name {
+ ($m:ident $extra:tt) => {
+ $m! {
+ $extra
+ pub trait $name $($methods)*
+ }
+ }
+ }
+
+ remove_sections! { []
+ $(#[$doc])*
+ pub trait $name $($methods)*
+
+ // This is where the trait definition is reproduced by the macro.
+ // It makes the source links point to this place!
+ //
+ // I'm sorry, you'll have to find the source by looking at the
+ // source of the module the trait is defined in.
+ //
+ // We use this nifty macro so that we can automatically generate
+ // delegation trait impls and implement the graph traits for more
+ // types and combinators.
+ }
+ }
+}
+
+macro_rules! remove_sections_inner {
+ ([$($stack:tt)*]) => {
+ $($stack)*
+ };
+ // escape the following tt
+ ([$($stack:tt)*] @escape $_x:tt $($t:tt)*) => {
+ remove_sections_inner!([$($stack)*] $($t)*);
+ };
+ ([$($stack:tt)*] @section $x:ident $($t:tt)*) => {
+ remove_sections_inner!([$($stack)*] $($t)*);
+ };
+ ([$($stack:tt)*] $t:tt $($tail:tt)*) => {
+ remove_sections_inner!([$($stack)* $t] $($tail)*);
+ };
+}
+
+// This is the outer layer, just find the { } of the actual trait definition
+// recurse once into { }, but not more.
+macro_rules! remove_sections {
+ ([$($stack:tt)*]) => {
+ $($stack)*
+ };
+ ([$($stack:tt)*] { $($tail:tt)* }) => {
+ $($stack)* {
+ remove_sections_inner!([] $($tail)*);
+ }
+ };
+ ([$($stack:tt)*] $t:tt $($tail:tt)*) => {
+ remove_sections!([$($stack)* $t] $($tail)*);
+ };
+}
+
+macro_rules! deref {
+ ($e:expr) => {
+ *$e
+ };
+}
+macro_rules! deref_twice {
+ ($e:expr) => {
+ **$e
+ };
+}
+
+/// Implement a trait by delegation. By default as if we are delegating
+/// from &G to G.
+macro_rules! delegate_impl {
+ ([] $($rest:tt)*) => {
+ delegate_impl! { [['a, G], G, &'a G, deref] $($rest)* }
+ };
+ ([[$($param:tt)*], $self_type:ident, $self_wrap:ty, $self_map:ident]
+ pub trait $name:ident $(: $sup:ident)* $(+ $more_sup:ident)* {
+
+ // "Escaped" associated types. Stripped before making the `trait`
+ // itself, but forwarded when delegating impls.
+ $(
+ @escape [type $assoc_name_ext:ident]
+ // Associated types. Forwarded.
+ )*
+ $(
+ @section type
+ $(
+ $(#[$_assoc_attr:meta])*
+ type $assoc_name:ident $(: $assoc_bound:ty)*;
+ )+
+ )*
+ // Methods. Forwarded. Using $self_map!(self) around the self argument.
+ // Methods must use receiver `self` or explicit type like `self: &Self`
+ // &self and &mut self are _not_ supported.
+ $(
+ @section self
+ $(
+ $(#[$_method_attr:meta])*
+ fn $method_name:ident(self $(: $self_selftype:ty)* $(,$marg:ident : $marg_ty:ty)*) $(-> $mret:ty)?;
+ )+
+ )*
+ // Arbitrary tail that is ignored when forwarding.
+ $(
+ @section nodelegate
+ $($tail:tt)*
+ )*
+ }) => {
+ impl<$($param)*> $name for $self_wrap where $self_type: $name {
+ $(
+ $(
+ type $assoc_name = $self_type::$assoc_name;
+ )*
+ )*
+ $(
+ type $assoc_name_ext = $self_type::$assoc_name_ext;
+ )*
+ $(
+ $(
+ fn $method_name(self $(: $self_selftype)* $(,$marg: $marg_ty)*) $(-> $mret)? {
+ $self_map!(self).$method_name($($marg),*)
+ }
+ )*
+ )*
+ }
+ }
+}
diff --git a/vendor/petgraph/src/visit/mod.rs b/vendor/petgraph/src/visit/mod.rs
new file mode 100644
index 000000000..d34979aa3
--- /dev/null
+++ b/vendor/petgraph/src/visit/mod.rs
@@ -0,0 +1,755 @@
+//! Graph traits and graph traversals.
+//!
+//! ### The `Into-` Traits
+//!
+//! Graph traits like [`IntoNeighbors`][in] create iterators and use the same
+//! pattern that `IntoIterator` does: the trait takes a reference to a graph,
+//! and produces an iterator. These traits are quite composable, but with the
+//! limitation that they only use shared references to graphs.
+//!
+//! ### Graph Traversal
+//!
+//! [`Dfs`](struct.Dfs.html), [`Bfs`][bfs], [`DfsPostOrder`][dfspo] and
+//! [`Topo`][topo] are basic visitors and they use “walker” methods: the
+//! visitors don't hold the graph as borrowed during traversal, only for the
+//! `.next()` call on the walker. They can be converted to iterators
+//! through the [`Walker`][w] trait.
+//!
+//! There is also the callback based traversal [`depth_first_search`][dfs].
+//!
+//! [bfs]: struct.Bfs.html
+//! [dfspo]: struct.DfsPostOrder.html
+//! [topo]: struct.Topo.html
+//! [dfs]: fn.depth_first_search.html
+//! [w]: trait.Walker.html
+//!
+//! ### Other Graph Traits
+//!
+//! The traits are rather loosely coupled at the moment (which is intentional,
+//! but will develop a bit), and there are traits missing that could be added.
+//!
+//! Not much is needed to be able to use the visitors on a graph. A graph
+//! needs to define [`GraphBase`][gb], [`IntoNeighbors`][in] and
+//! [`Visitable`][vis] as a minimum.
+//!
+//! [gb]: trait.GraphBase.html
+//! [in]: trait.IntoNeighbors.html
+//! [vis]: trait.Visitable.html
+//!
+
+// filter, reversed have their `mod` lines at the end,
+// so that they can use the trait template macros
+pub use self::filter::*;
+pub use self::reversed::*;
+
+#[macro_use]
+mod macros;
+
+mod dfsvisit;
+mod traversal;
+pub use self::dfsvisit::*;
+pub use self::traversal::*;
+
+use fixedbitset::FixedBitSet;
+use std::collections::HashSet;
+use std::hash::{BuildHasher, Hash};
+
+use super::{graph, EdgeType};
+use crate::graph::NodeIndex;
+#[cfg(feature = "graphmap")]
+use crate::prelude::GraphMap;
+#[cfg(feature = "stable_graph")]
+use crate::prelude::StableGraph;
+use crate::prelude::{Direction, Graph};
+
+use crate::graph::Frozen;
+use crate::graph::IndexType;
+#[cfg(feature = "stable_graph")]
+use crate::stable_graph;
+
+#[cfg(feature = "graphmap")]
+use crate::graphmap::{self, NodeTrait};
+
+trait_template! {
+/// Base graph trait: defines the associated node identifier and
+/// edge identifier types.
+pub trait GraphBase {
+ // FIXME: We can drop this escape/nodelegate stuff in Rust 1.18
+ @escape [type NodeId]
+ @escape [type EdgeId]
+ @section nodelegate
+ /// edge identifier
+ type EdgeId: Copy + PartialEq;
+ /// node identifier
+ type NodeId: Copy + PartialEq;
+}
+}
+
+GraphBase! {delegate_impl []}
+GraphBase! {delegate_impl [['a, G], G, &'a mut G, deref]}
+
+/// A copyable reference to a graph.
+pub trait GraphRef: Copy + GraphBase {}
+
+impl<'a, G> GraphRef for &'a G where G: GraphBase {}
+
+impl<'a, G> GraphBase for Frozen<'a, G>
+where
+ G: GraphBase,
+{
+ type NodeId = G::NodeId;
+ type EdgeId = G::EdgeId;
+}
+
+#[cfg(feature = "stable_graph")]
+impl<'a, N, E: 'a, Ty, Ix> IntoNeighbors for &'a StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Neighbors = stable_graph::Neighbors<'a, E, Ix>;
+ fn neighbors(self, n: Self::NodeId) -> Self::Neighbors {
+ (*self).neighbors(n)
+ }
+}
+
+#[cfg(feature = "graphmap")]
+impl<'a, N: 'a, E, Ty> IntoNeighbors for &'a GraphMap<N, E, Ty>
+where
+ N: Copy + Ord + Hash,
+ Ty: EdgeType,
+{
+ type Neighbors = graphmap::Neighbors<'a, N, Ty>;
+ fn neighbors(self, n: Self::NodeId) -> Self::Neighbors {
+ self.neighbors(n)
+ }
+}
+
+trait_template! {
+/// Access to the neighbors of each node
+///
+/// The neighbors are, depending on the graph’s edge type:
+///
+/// - `Directed`: All targets of edges from `a`.
+/// - `Undirected`: All other endpoints of edges connected to `a`.
+pub trait IntoNeighbors : GraphRef {
+ @section type
+ type Neighbors: Iterator<Item=Self::NodeId>;
+ @section self
+ /// Return an iterator of the neighbors of node `a`.
+ fn neighbors(self: Self, a: Self::NodeId) -> Self::Neighbors;
+}
+}
+
+IntoNeighbors! {delegate_impl []}
+
+trait_template! {
+/// Access to the neighbors of each node, through incoming or outgoing edges.
+///
+/// Depending on the graph’s edge type, the neighbors of a given directionality
+/// are:
+///
+/// - `Directed`, `Outgoing`: All targets of edges from `a`.
+/// - `Directed`, `Incoming`: All sources of edges to `a`.
+/// - `Undirected`: All other endpoints of edges connected to `a`.
+pub trait IntoNeighborsDirected : IntoNeighbors {
+ @section type
+ type NeighborsDirected: Iterator<Item=Self::NodeId>;
+ @section self
+ fn neighbors_directed(self, n: Self::NodeId, d: Direction)
+ -> Self::NeighborsDirected;
+}
+}
+
+impl<'a, N, E: 'a, Ty, Ix> IntoNeighbors for &'a Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Neighbors = graph::Neighbors<'a, E, Ix>;
+ fn neighbors(self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix> {
+ Graph::neighbors(self, n)
+ }
+}
+
+impl<'a, N, E: 'a, Ty, Ix> IntoNeighborsDirected for &'a Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NeighborsDirected = graph::Neighbors<'a, E, Ix>;
+ fn neighbors_directed(
+ self,
+ n: graph::NodeIndex<Ix>,
+ d: Direction,
+ ) -> graph::Neighbors<'a, E, Ix> {
+ Graph::neighbors_directed(self, n, d)
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<'a, N, E: 'a, Ty, Ix> IntoNeighborsDirected for &'a StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NeighborsDirected = stable_graph::Neighbors<'a, E, Ix>;
+ fn neighbors_directed(self, n: graph::NodeIndex<Ix>, d: Direction) -> Self::NeighborsDirected {
+ StableGraph::neighbors_directed(self, n, d)
+ }
+}
+
+#[cfg(feature = "graphmap")]
+impl<'a, N: 'a, E, Ty> IntoNeighborsDirected for &'a GraphMap<N, E, Ty>
+where
+ N: Copy + Ord + Hash,
+ Ty: EdgeType,
+{
+ type NeighborsDirected = graphmap::NeighborsDirected<'a, N, Ty>;
+ fn neighbors_directed(self, n: N, dir: Direction) -> Self::NeighborsDirected {
+ self.neighbors_directed(n, dir)
+ }
+}
+
+trait_template! {
+/// Access to the edges of each node.
+///
+/// The edges are, depending on the graph’s edge type:
+///
+/// - `Directed`: All edges from `a`.
+/// - `Undirected`: All edges connected to `a`.
+///
+/// This is an extended version of the trait `IntoNeighbors`; the former
+/// only iterates over the target node identifiers, while this trait
+/// yields edge references (trait [`EdgeRef`][er]).
+///
+/// [er]: trait.EdgeRef.html
+pub trait IntoEdges : IntoEdgeReferences + IntoNeighbors {
+ @section type
+ type Edges: Iterator<Item=Self::EdgeRef>;
+ @section self
+ fn edges(self, a: Self::NodeId) -> Self::Edges;
+}
+}
+
+IntoEdges! {delegate_impl []}
+
+trait_template! {
+/// Access to all edges of each node, in the specified direction.
+///
+/// The edges are, depending on the direction and the graph’s edge type:
+///
+///
+/// - `Directed`, `Outgoing`: All edges from `a`.
+/// - `Directed`, `Incoming`: All edges to `a`.
+/// - `Undirected`, `Outgoing`: All edges connected to `a`, with `a` being the source of each edge.
+/// - `Undirected`, `Incoming`: All edges connected to `a`, with `a` being the target of each edge.
+///
+/// This is an extended version of the trait `IntoNeighborsDirected`; the former
+/// only iterates over the target node identifiers, while this trait
+/// yields edge references (trait [`EdgeRef`][er]).
+///
+/// [er]: trait.EdgeRef.html
+pub trait IntoEdgesDirected : IntoEdges + IntoNeighborsDirected {
+ @section type
+ type EdgesDirected: Iterator<Item=Self::EdgeRef>;
+ @section self
+ fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected;
+}
+}
+
+IntoEdgesDirected! {delegate_impl []}
+
+trait_template! {
+/// Access to the sequence of the graph’s `NodeId`s.
+pub trait IntoNodeIdentifiers : GraphRef {
+ @section type
+ type NodeIdentifiers: Iterator<Item=Self::NodeId>;
+ @section self
+ fn node_identifiers(self) -> Self::NodeIdentifiers;
+}
+}
+
+IntoNodeIdentifiers! {delegate_impl []}
+
+impl<'a, N, E: 'a, Ty, Ix> IntoNodeIdentifiers for &'a Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeIdentifiers = graph::NodeIndices<Ix>;
+ fn node_identifiers(self) -> graph::NodeIndices<Ix> {
+ Graph::node_indices(self)
+ }
+}
+
+impl<N, E, Ty, Ix> NodeCount for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_count(&self) -> usize {
+ self.node_count()
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<'a, N, E: 'a, Ty, Ix> IntoNodeIdentifiers for &'a StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeIdentifiers = stable_graph::NodeIndices<'a, N, Ix>;
+ fn node_identifiers(self) -> Self::NodeIdentifiers {
+ StableGraph::node_indices(self)
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> NodeCount for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_count(&self) -> usize {
+ self.node_count()
+ }
+}
+
+IntoNeighborsDirected! {delegate_impl []}
+
+trait_template! {
+/// Define associated data for nodes and edges
+pub trait Data : GraphBase {
+ @section type
+ type NodeWeight;
+ type EdgeWeight;
+}
+}
+
+Data! {delegate_impl []}
+Data! {delegate_impl [['a, G], G, &'a mut G, deref]}
+
+/// An edge reference.
+///
+/// Edge references are used by traits `IntoEdges` and `IntoEdgeReferences`.
+pub trait EdgeRef: Copy {
+ type NodeId;
+ type EdgeId;
+ type Weight;
+ /// The source node of the edge.
+ fn source(&self) -> Self::NodeId;
+ /// The target node of the edge.
+ fn target(&self) -> Self::NodeId;
+ /// A reference to the weight of the edge.
+ fn weight(&self) -> &Self::Weight;
+ /// The edge’s identifier.
+ fn id(&self) -> Self::EdgeId;
+}
+
+impl<'a, N, E> EdgeRef for (N, N, &'a E)
+where
+ N: Copy,
+{
+ type NodeId = N;
+ type EdgeId = (N, N);
+ type Weight = E;
+
+ fn source(&self) -> N {
+ self.0
+ }
+ fn target(&self) -> N {
+ self.1
+ }
+ fn weight(&self) -> &E {
+ self.2
+ }
+ fn id(&self) -> (N, N) {
+ (self.0, self.1)
+ }
+}
+
+/// A node reference.
+pub trait NodeRef: Copy {
+ type NodeId;
+ type Weight;
+ fn id(&self) -> Self::NodeId;
+ fn weight(&self) -> &Self::Weight;
+}
+
+trait_template! {
+/// Access to the sequence of the graph’s nodes
+pub trait IntoNodeReferences : Data + IntoNodeIdentifiers {
+ @section type
+ type NodeRef: NodeRef<NodeId=Self::NodeId, Weight=Self::NodeWeight>;
+ type NodeReferences: Iterator<Item=Self::NodeRef>;
+ @section self
+ fn node_references(self) -> Self::NodeReferences;
+}
+}
+
+IntoNodeReferences! {delegate_impl []}
+
+impl<Id> NodeRef for (Id, ())
+where
+ Id: Copy,
+{
+ type NodeId = Id;
+ type Weight = ();
+ fn id(&self) -> Self::NodeId {
+ self.0
+ }
+ fn weight(&self) -> &Self::Weight {
+ static DUMMY: () = ();
+ &DUMMY
+ }
+}
+
+impl<'a, Id, W> NodeRef for (Id, &'a W)
+where
+ Id: Copy,
+{
+ type NodeId = Id;
+ type Weight = W;
+ fn id(&self) -> Self::NodeId {
+ self.0
+ }
+ fn weight(&self) -> &Self::Weight {
+ self.1
+ }
+}
+
+trait_template! {
+/// Access to the sequence of the graph’s edges
+pub trait IntoEdgeReferences : Data + GraphRef {
+ @section type
+ type EdgeRef: EdgeRef<NodeId=Self::NodeId, EdgeId=Self::EdgeId,
+ Weight=Self::EdgeWeight>;
+ type EdgeReferences: Iterator<Item=Self::EdgeRef>;
+ @section self
+ fn edge_references(self) -> Self::EdgeReferences;
+}
+}
+
+IntoEdgeReferences! {delegate_impl [] }
+
+#[cfg(feature = "graphmap")]
+impl<N, E, Ty> Data for GraphMap<N, E, Ty>
+where
+ N: Copy + PartialEq,
+ Ty: EdgeType,
+{
+ type NodeWeight = N;
+ type EdgeWeight = E;
+}
+
+trait_template! {
+ /// Edge kind property (directed or undirected edges)
+pub trait GraphProp : GraphBase {
+ @section type
+ /// The kind edges in the graph.
+ type EdgeType: EdgeType;
+
+ @section nodelegate
+ fn is_directed(&self) -> bool {
+ <Self::EdgeType>::is_directed()
+ }
+}
+}
+
+GraphProp! {delegate_impl []}
+
+impl<N, E, Ty, Ix> GraphProp for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type EdgeType = Ty;
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> GraphProp for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type EdgeType = Ty;
+}
+
+#[cfg(feature = "graphmap")]
+impl<N, E, Ty> GraphProp for GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ type EdgeType = Ty;
+}
+
+impl<'a, N: 'a, E: 'a, Ty, Ix> IntoEdgeReferences for &'a Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type EdgeRef = graph::EdgeReference<'a, E, Ix>;
+ type EdgeReferences = graph::EdgeReferences<'a, E, Ix>;
+ fn edge_references(self) -> Self::EdgeReferences {
+ (*self).edge_references()
+ }
+}
+
+trait_template! {
+ /// The graph’s `NodeId`s map to indices
+ pub trait NodeIndexable : GraphBase {
+ @section self
+ /// Return an upper bound of the node indices in the graph
+ /// (suitable for the size of a bitmap).
+ fn node_bound(self: &Self) -> usize;
+ /// Convert `a` to an integer index.
+ fn to_index(self: &Self, a: Self::NodeId) -> usize;
+ /// Convert `i` to a node index
+ fn from_index(self: &Self, i: usize) -> Self::NodeId;
+ }
+}
+
+NodeIndexable! {delegate_impl []}
+
+trait_template! {
+/// A graph with a known node count.
+pub trait NodeCount : GraphBase {
+ @section self
+ fn node_count(self: &Self) -> usize;
+}
+}
+
+NodeCount! {delegate_impl []}
+
+trait_template! {
+/// The graph’s `NodeId`s map to indices, in a range without holes.
+///
+/// The graph's node identifiers correspond to exactly the indices
+/// `0..self.node_bound()`.
+pub trait NodeCompactIndexable : NodeIndexable + NodeCount { }
+}
+
+NodeCompactIndexable! {delegate_impl []}
+
+impl<N, E, Ty, Ix> NodeIndexable for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_bound(&self) -> usize {
+ self.node_count()
+ }
+ fn to_index(&self, ix: NodeIndex<Ix>) -> usize {
+ ix.index()
+ }
+ fn from_index(&self, ix: usize) -> Self::NodeId {
+ NodeIndex::new(ix)
+ }
+}
+
+impl<N, E, Ty, Ix> NodeCompactIndexable for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+}
+
+/// A mapping for storing the visited status for NodeId `N`.
+pub trait VisitMap<N> {
+ /// Mark `a` as visited.
+ ///
+ /// Return **true** if this is the first visit, false otherwise.
+ fn visit(&mut self, a: N) -> bool;
+
+ /// Return whether `a` has been visited before.
+ fn is_visited(&self, a: &N) -> bool;
+}
+
+impl<Ix> VisitMap<graph::NodeIndex<Ix>> for FixedBitSet
+where
+ Ix: IndexType,
+{
+ fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
+ !self.put(x.index())
+ }
+ fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
+ self.contains(x.index())
+ }
+}
+
+impl<Ix> VisitMap<graph::EdgeIndex<Ix>> for FixedBitSet
+where
+ Ix: IndexType,
+{
+ fn visit(&mut self, x: graph::EdgeIndex<Ix>) -> bool {
+ !self.put(x.index())
+ }
+ fn is_visited(&self, x: &graph::EdgeIndex<Ix>) -> bool {
+ self.contains(x.index())
+ }
+}
+
+impl<Ix> VisitMap<Ix> for FixedBitSet
+where
+ Ix: IndexType,
+{
+ fn visit(&mut self, x: Ix) -> bool {
+ !self.put(x.index())
+ }
+ fn is_visited(&self, x: &Ix) -> bool {
+ self.contains(x.index())
+ }
+}
+
+impl<N, S> VisitMap<N> for HashSet<N, S>
+where
+ N: Hash + Eq,
+ S: BuildHasher,
+{
+ fn visit(&mut self, x: N) -> bool {
+ self.insert(x)
+ }
+ fn is_visited(&self, x: &N) -> bool {
+ self.contains(x)
+ }
+}
+
+trait_template! {
+/// A graph that can create a map that tracks the visited status of its nodes.
+pub trait Visitable : GraphBase {
+ @section type
+ /// The associated map type
+ type Map: VisitMap<Self::NodeId>;
+ @section self
+ /// Create a new visitor map
+ fn visit_map(self: &Self) -> Self::Map;
+ /// Reset the visitor map (and resize to new size of graph if needed)
+ fn reset_map(self: &Self, map: &mut Self::Map);
+}
+}
+Visitable! {delegate_impl []}
+
+impl<N, E, Ty, Ix> GraphBase for Graph<N, E, Ty, Ix>
+where
+ Ix: IndexType,
+{
+ type NodeId = graph::NodeIndex<Ix>;
+ type EdgeId = graph::EdgeIndex<Ix>;
+}
+
+impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Map = FixedBitSet;
+ fn visit_map(&self) -> FixedBitSet {
+ FixedBitSet::with_capacity(self.node_count())
+ }
+
+ fn reset_map(&self, map: &mut Self::Map) {
+ map.clear();
+ map.grow(self.node_count());
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> GraphBase for StableGraph<N, E, Ty, Ix>
+where
+ Ix: IndexType,
+{
+ type NodeId = graph::NodeIndex<Ix>;
+ type EdgeId = graph::EdgeIndex<Ix>;
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> Visitable for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Map = FixedBitSet;
+ fn visit_map(&self) -> FixedBitSet {
+ FixedBitSet::with_capacity(self.node_bound())
+ }
+ fn reset_map(&self, map: &mut Self::Map) {
+ map.clear();
+ map.grow(self.node_bound());
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> Data for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeWeight = N;
+ type EdgeWeight = E;
+}
+
+#[cfg(feature = "graphmap")]
+impl<N, E, Ty> GraphBase for GraphMap<N, E, Ty>
+where
+ N: Copy + PartialEq,
+{
+ type NodeId = N;
+ type EdgeId = (N, N);
+}
+
+#[cfg(feature = "graphmap")]
+impl<N, E, Ty> Visitable for GraphMap<N, E, Ty>
+where
+ N: Copy + Ord + Hash,
+ Ty: EdgeType,
+{
+ type Map = HashSet<N>;
+ fn visit_map(&self) -> HashSet<N> {
+ HashSet::with_capacity(self.node_count())
+ }
+ fn reset_map(&self, map: &mut Self::Map) {
+ map.clear();
+ }
+}
+
+trait_template! {
+/// Create or access the adjacency matrix of a graph.
+///
+/// The implementor can either create an adjacency matrix, or it can return
+/// a placeholder if it has the needed representation internally.
+pub trait GetAdjacencyMatrix : GraphBase {
+ @section type
+ /// The associated adjacency matrix type
+ type AdjMatrix;
+ @section self
+ /// Create the adjacency matrix
+ fn adjacency_matrix(self: &Self) -> Self::AdjMatrix;
+ /// Return true if there is an edge from `a` to `b`, false otherwise.
+ ///
+ /// Computes in O(1) time.
+ fn is_adjacent(self: &Self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
+}
+}
+
+GetAdjacencyMatrix! {delegate_impl []}
+
+#[cfg(feature = "graphmap")]
+/// The `GraphMap` keeps an adjacency matrix internally.
+impl<N, E, Ty> GetAdjacencyMatrix for GraphMap<N, E, Ty>
+where
+ N: Copy + Ord + Hash,
+ Ty: EdgeType,
+{
+ type AdjMatrix = ();
+ #[inline]
+ fn adjacency_matrix(&self) {}
+ #[inline]
+ fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
+ self.contains_edge(a, b)
+ }
+}
+
+mod filter;
+mod reversed;
diff --git a/vendor/petgraph/src/visit/reversed.rs b/vendor/petgraph/src/visit/reversed.rs
new file mode 100644
index 000000000..70a6f578f
--- /dev/null
+++ b/vendor/petgraph/src/visit/reversed.rs
@@ -0,0 +1,170 @@
+use crate::{Direction, Incoming};
+
+use crate::visit::{
+ Data, EdgeRef, GraphBase, GraphProp, GraphRef, IntoEdgeReferences, IntoEdges,
+ IntoEdgesDirected, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers,
+ IntoNodeReferences, NodeCompactIndexable, NodeCount, NodeIndexable, Visitable,
+};
+
+/// An edge-reversing graph adaptor.
+///
+/// All edges have the opposite direction with `Reversed`.
+#[derive(Copy, Clone, Debug)]
+pub struct Reversed<G>(pub G);
+
+impl<G: GraphBase> GraphBase for Reversed<G> {
+ type NodeId = G::NodeId;
+ type EdgeId = G::EdgeId;
+}
+
+impl<G: GraphRef> GraphRef for Reversed<G> {}
+
+Data! {delegate_impl [[G], G, Reversed<G>, access0]}
+
+impl<G> IntoNeighbors for Reversed<G>
+where
+ G: IntoNeighborsDirected,
+{
+ type Neighbors = G::NeighborsDirected;
+ fn neighbors(self, n: G::NodeId) -> G::NeighborsDirected {
+ self.0.neighbors_directed(n, Incoming)
+ }
+}
+
+impl<G> IntoNeighborsDirected for Reversed<G>
+where
+ G: IntoNeighborsDirected,
+{
+ type NeighborsDirected = G::NeighborsDirected;
+ fn neighbors_directed(self, n: G::NodeId, d: Direction) -> G::NeighborsDirected {
+ self.0.neighbors_directed(n, d.opposite())
+ }
+}
+
+impl<G> IntoEdges for Reversed<G>
+where
+ G: IntoEdgesDirected,
+{
+ type Edges = ReversedEdges<G::EdgesDirected>;
+ fn edges(self, a: Self::NodeId) -> Self::Edges {
+ ReversedEdges {
+ iter: self.0.edges_directed(a, Incoming),
+ }
+ }
+}
+
+impl<G> IntoEdgesDirected for Reversed<G>
+where
+ G: IntoEdgesDirected,
+{
+ type EdgesDirected = ReversedEdges<G::EdgesDirected>;
+ fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::Edges {
+ ReversedEdges {
+ iter: self.0.edges_directed(a, dir.opposite()),
+ }
+ }
+}
+
+impl<G: Visitable> Visitable for Reversed<G> {
+ type Map = G::Map;
+ fn visit_map(&self) -> G::Map {
+ self.0.visit_map()
+ }
+ fn reset_map(&self, map: &mut Self::Map) {
+ self.0.reset_map(map);
+ }
+}
+
+/// A reversed edges iterator.
+pub struct ReversedEdges<I> {
+ iter: I,
+}
+
+impl<I> Iterator for ReversedEdges<I>
+where
+ I: Iterator,
+ I::Item: EdgeRef,
+{
+ type Item = ReversedEdgeReference<I::Item>;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(ReversedEdgeReference)
+ }
+}
+
+/// A reversed edge reference
+#[derive(Copy, Clone, Debug)]
+pub struct ReversedEdgeReference<R>(R);
+
+impl<R> ReversedEdgeReference<R> {
+ /// Return the original, unreversed edge reference.
+ pub fn as_unreversed(&self) -> &R { &self.0 }
+
+ /// Consume `self` and return the original, unreversed edge reference.
+ pub fn into_unreversed(self) -> R {
+ self.0
+ }
+}
+
+/// An edge reference
+impl<R> EdgeRef for ReversedEdgeReference<R>
+where
+ R: EdgeRef,
+{
+ type NodeId = R::NodeId;
+ type EdgeId = R::EdgeId;
+ type Weight = R::Weight;
+ fn source(&self) -> Self::NodeId {
+ self.0.target()
+ }
+ fn target(&self) -> Self::NodeId {
+ self.0.source()
+ }
+ fn weight(&self) -> &Self::Weight {
+ self.0.weight()
+ }
+ fn id(&self) -> Self::EdgeId {
+ self.0.id()
+ }
+}
+
+impl<G> IntoEdgeReferences for Reversed<G>
+where
+ G: IntoEdgeReferences,
+{
+ type EdgeRef = ReversedEdgeReference<G::EdgeRef>;
+ type EdgeReferences = ReversedEdgeReferences<G::EdgeReferences>;
+ fn edge_references(self) -> Self::EdgeReferences {
+ ReversedEdgeReferences {
+ iter: self.0.edge_references(),
+ }
+ }
+}
+
+/// A reversed edge references iterator.
+pub struct ReversedEdgeReferences<I> {
+ iter: I,
+}
+
+impl<I> Iterator for ReversedEdgeReferences<I>
+where
+ I: Iterator,
+ I::Item: EdgeRef,
+{
+ type Item = ReversedEdgeReference<I::Item>;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(ReversedEdgeReference)
+ }
+}
+
+macro_rules! access0 {
+ ($e:expr) => {
+ $e.0
+ };
+}
+
+NodeIndexable! {delegate_impl [[G], G, Reversed<G>, access0]}
+NodeCompactIndexable! {delegate_impl [[G], G, Reversed<G>, access0]}
+IntoNodeIdentifiers! {delegate_impl [[G], G, Reversed<G>, access0]}
+IntoNodeReferences! {delegate_impl [[G], G, Reversed<G>, access0]}
+GraphProp! {delegate_impl [[G], G, Reversed<G>, access0]}
+NodeCount! {delegate_impl [[G], G, Reversed<G>, access0]}
diff --git a/vendor/petgraph/src/visit/traversal.rs b/vendor/petgraph/src/visit/traversal.rs
new file mode 100644
index 000000000..88782fa24
--- /dev/null
+++ b/vendor/petgraph/src/visit/traversal.rs
@@ -0,0 +1,519 @@
+use super::{GraphRef, IntoNodeIdentifiers, Reversed};
+use super::{IntoNeighbors, IntoNeighborsDirected, VisitMap, Visitable};
+use crate::Incoming;
+use std::collections::VecDeque;
+
+/// Visit nodes of a graph in a depth-first-search (DFS) emitting nodes in
+/// preorder (when they are first discovered).
+///
+/// The traversal starts at a given node and only traverses nodes reachable
+/// from it.
+///
+/// `Dfs` is not recursive.
+///
+/// `Dfs` does not itself borrow the graph, and because of this you can run
+/// a traversal over a graph while still retaining mutable access to it, if you
+/// use it like the following example:
+///
+/// ```
+/// use petgraph::Graph;
+/// use petgraph::visit::Dfs;
+///
+/// let mut graph = Graph::<_,()>::new();
+/// let a = graph.add_node(0);
+///
+/// let mut dfs = Dfs::new(&graph, a);
+/// while let Some(nx) = dfs.next(&graph) {
+/// // we can access `graph` mutably here still
+/// graph[nx] += 1;
+/// }
+///
+/// assert_eq!(graph[a], 1);
+/// ```
+///
+/// **Note:** The algorithm may not behave correctly if nodes are removed
+/// during iteration. It may not necessarily visit added nodes or edges.
+#[derive(Clone, Debug)]
+pub struct Dfs<N, VM> {
+ /// The stack of nodes to visit
+ pub stack: Vec<N>,
+ /// The map of discovered nodes
+ pub discovered: VM,
+}
+
+impl<N, VM> Default for Dfs<N, VM>
+where
+ VM: Default,
+{
+ fn default() -> Self {
+ Dfs {
+ stack: Vec::new(),
+ discovered: VM::default(),
+ }
+ }
+}
+
+impl<N, VM> Dfs<N, VM>
+where
+ N: Copy + PartialEq,
+ VM: VisitMap<N>,
+{
+ /// Create a new **Dfs**, using the graph's visitor map, and put **start**
+ /// in the stack of nodes to visit.
+ pub fn new<G>(graph: G, start: N) -> Self
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ let mut dfs = Dfs::empty(graph);
+ dfs.move_to(start);
+ dfs
+ }
+
+ /// Create a `Dfs` from a vector and a visit map
+ pub fn from_parts(stack: Vec<N>, discovered: VM) -> Self {
+ Dfs { stack, discovered }
+ }
+
+ /// Clear the visit state
+ pub fn reset<G>(&mut self, graph: G)
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ graph.reset_map(&mut self.discovered);
+ self.stack.clear();
+ }
+
+ /// Create a new **Dfs** using the graph's visitor map, and no stack.
+ pub fn empty<G>(graph: G) -> Self
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ Dfs {
+ stack: Vec::new(),
+ discovered: graph.visit_map(),
+ }
+ }
+
+ /// Keep the discovered map, but clear the visit stack and restart
+ /// the dfs from a particular node.
+ pub fn move_to(&mut self, start: N) {
+ self.stack.clear();
+ self.stack.push(start);
+ }
+
+ /// Return the next node in the dfs, or **None** if the traversal is done.
+ pub fn next<G>(&mut self, graph: G) -> Option<N>
+ where
+ G: IntoNeighbors<NodeId = N>,
+ {
+ while let Some(node) = self.stack.pop() {
+ if self.discovered.visit(node) {
+ for succ in graph.neighbors(node) {
+ if !self.discovered.is_visited(&succ) {
+ self.stack.push(succ);
+ }
+ }
+ return Some(node);
+ }
+ }
+ None
+ }
+}
+
+/// Visit nodes in a depth-first-search (DFS) emitting nodes in postorder
+/// (each node after all its descendants have been emitted).
+///
+/// `DfsPostOrder` is not recursive.
+///
+/// The traversal starts at a given node and only traverses nodes reachable
+/// from it.
+#[derive(Clone, Debug)]
+pub struct DfsPostOrder<N, VM> {
+ /// The stack of nodes to visit
+ pub stack: Vec<N>,
+ /// The map of discovered nodes
+ pub discovered: VM,
+ /// The map of finished nodes
+ pub finished: VM,
+}
+
+impl<N, VM> Default for DfsPostOrder<N, VM>
+where
+ VM: Default,
+{
+ fn default() -> Self {
+ DfsPostOrder {
+ stack: Vec::new(),
+ discovered: VM::default(),
+ finished: VM::default(),
+ }
+ }
+}
+
+impl<N, VM> DfsPostOrder<N, VM>
+where
+ N: Copy + PartialEq,
+ VM: VisitMap<N>,
+{
+ /// Create a new `DfsPostOrder` using the graph's visitor map, and put
+ /// `start` in the stack of nodes to visit.
+ pub fn new<G>(graph: G, start: N) -> Self
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ let mut dfs = Self::empty(graph);
+ dfs.move_to(start);
+ dfs
+ }
+
+ /// Create a new `DfsPostOrder` using the graph's visitor map, and no stack.
+ pub fn empty<G>(graph: G) -> Self
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ DfsPostOrder {
+ stack: Vec::new(),
+ discovered: graph.visit_map(),
+ finished: graph.visit_map(),
+ }
+ }
+
+ /// Clear the visit state
+ pub fn reset<G>(&mut self, graph: G)
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ graph.reset_map(&mut self.discovered);
+ graph.reset_map(&mut self.finished);
+ self.stack.clear();
+ }
+
+ /// Keep the discovered and finished map, but clear the visit stack and restart
+ /// the dfs from a particular node.
+ pub fn move_to(&mut self, start: N) {
+ self.stack.clear();
+ self.stack.push(start);
+ }
+
+ /// Return the next node in the traversal, or `None` if the traversal is done.
+ pub fn next<G>(&mut self, graph: G) -> Option<N>
+ where
+ G: IntoNeighbors<NodeId = N>,
+ {
+ while let Some(&nx) = self.stack.last() {
+ if self.discovered.visit(nx) {
+ // First time visiting `nx`: Push neighbors, don't pop `nx`
+ for succ in graph.neighbors(nx) {
+ if !self.discovered.is_visited(&succ) {
+ self.stack.push(succ);
+ }
+ }
+ } else {
+ self.stack.pop();
+ if self.finished.visit(nx) {
+ // Second time: All reachable nodes must have been finished
+ return Some(nx);
+ }
+ }
+ }
+ None
+ }
+}
+
+/// A breadth first search (BFS) of a graph.
+///
+/// The traversal starts at a given node and only traverses nodes reachable
+/// from it.
+///
+/// `Bfs` is not recursive.
+///
+/// `Bfs` does not itself borrow the graph, and because of this you can run
+/// a traversal over a graph while still retaining mutable access to it, if you
+/// use it like the following example:
+///
+/// ```
+/// use petgraph::Graph;
+/// use petgraph::visit::Bfs;
+///
+/// let mut graph = Graph::<_,()>::new();
+/// let a = graph.add_node(0);
+///
+/// let mut bfs = Bfs::new(&graph, a);
+/// while let Some(nx) = bfs.next(&graph) {
+/// // we can access `graph` mutably here still
+/// graph[nx] += 1;
+/// }
+///
+/// assert_eq!(graph[a], 1);
+/// ```
+///
+/// **Note:** The algorithm may not behave correctly if nodes are removed
+/// during iteration. It may not necessarily visit added nodes or edges.
+#[derive(Clone)]
+pub struct Bfs<N, VM> {
+ /// The queue of nodes to visit
+ pub stack: VecDeque<N>,
+ /// The map of discovered nodes
+ pub discovered: VM,
+}
+
+impl<N, VM> Default for Bfs<N, VM>
+where
+ VM: Default,
+{
+ fn default() -> Self {
+ Bfs {
+ stack: VecDeque::new(),
+ discovered: VM::default(),
+ }
+ }
+}
+
+impl<N, VM> Bfs<N, VM>
+where
+ N: Copy + PartialEq,
+ VM: VisitMap<N>,
+{
+ /// Create a new **Bfs**, using the graph's visitor map, and put **start**
+ /// in the stack of nodes to visit.
+ pub fn new<G>(graph: G, start: N) -> Self
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ let mut discovered = graph.visit_map();
+ discovered.visit(start);
+ let mut stack = VecDeque::new();
+ stack.push_front(start);
+ Bfs { stack, discovered }
+ }
+
+ /// Return the next node in the bfs, or **None** if the traversal is done.
+ pub fn next<G>(&mut self, graph: G) -> Option<N>
+ where
+ G: IntoNeighbors<NodeId = N>,
+ {
+ if let Some(node) = self.stack.pop_front() {
+ for succ in graph.neighbors(node) {
+ if self.discovered.visit(succ) {
+ self.stack.push_back(succ);
+ }
+ }
+
+ return Some(node);
+ }
+ None
+ }
+}
+
+/// A topological order traversal for a graph.
+///
+/// **Note** that `Topo` only visits nodes that are not part of cycles,
+/// i.e. nodes in a true DAG. Use other visitors like `DfsPostOrder` or
+/// algorithms like kosaraju_scc to handle graphs with possible cycles.
+#[derive(Clone)]
+pub struct Topo<N, VM> {
+ tovisit: Vec<N>,
+ ordered: VM,
+}
+
+impl<N, VM> Default for Topo<N, VM>
+where
+ VM: Default,
+{
+ fn default() -> Self {
+ Topo {
+ tovisit: Vec::new(),
+ ordered: VM::default(),
+ }
+ }
+}
+
+impl<N, VM> Topo<N, VM>
+where
+ N: Copy + PartialEq,
+ VM: VisitMap<N>,
+{
+ /// Create a new `Topo`, using the graph's visitor map, and put all
+ /// initial nodes in the to visit list.
+ pub fn new<G>(graph: G) -> Self
+ where
+ G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
+ {
+ let mut topo = Self::empty(graph);
+ topo.extend_with_initials(graph);
+ topo
+ }
+
+ fn extend_with_initials<G>(&mut self, g: G)
+ where
+ G: IntoNodeIdentifiers + IntoNeighborsDirected<NodeId = N>,
+ {
+ // find all initial nodes (nodes without incoming edges)
+ self.tovisit.extend(
+ g.node_identifiers()
+ .filter(move |&a| g.neighbors_directed(a, Incoming).next().is_none()),
+ );
+ }
+
+ /* Private until it has a use */
+ /// Create a new `Topo`, using the graph's visitor map with *no* starting
+ /// index specified.
+ fn empty<G>(graph: G) -> Self
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ Topo {
+ ordered: graph.visit_map(),
+ tovisit: Vec::new(),
+ }
+ }
+
+ /// Clear visited state, and put all initial nodes in the to visit list.
+ pub fn reset<G>(&mut self, graph: G)
+ where
+ G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
+ {
+ graph.reset_map(&mut self.ordered);
+ self.tovisit.clear();
+ self.extend_with_initials(graph);
+ }
+
+ /// Return the next node in the current topological order traversal, or
+ /// `None` if the traversal is at the end.
+ ///
+ /// *Note:* The graph may not have a complete topological order, and the only
+ /// way to know is to run the whole traversal and make sure it visits every node.
+ pub fn next<G>(&mut self, g: G) -> Option<N>
+ where
+ G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
+ {
+ // Take an unvisited element and find which of its neighbors are next
+ while let Some(nix) = self.tovisit.pop() {
+ if self.ordered.is_visited(&nix) {
+ continue;
+ }
+ self.ordered.visit(nix);
+ for neigh in g.neighbors(nix) {
+ // Look at each neighbor, and those that only have incoming edges
+ // from the already ordered list, they are the next to visit.
+ if Reversed(g)
+ .neighbors(neigh)
+ .all(|b| self.ordered.is_visited(&b))
+ {
+ self.tovisit.push(neigh);
+ }
+ }
+ return Some(nix);
+ }
+ None
+ }
+}
+
+/// A walker is a traversal state, but where part of the traversal
+/// information is supplied manually to each next call.
+///
+/// This for example allows graph traversals that don't hold a borrow of the
+/// graph they are traversing.
+pub trait Walker<Context> {
+ type Item;
+ /// Advance to the next item
+ fn walk_next(&mut self, context: Context) -> Option<Self::Item>;
+
+ /// Create an iterator out of the walker and given `context`.
+ fn iter(self, context: Context) -> WalkerIter<Self, Context>
+ where
+ Self: Sized,
+ Context: Clone,
+ {
+ WalkerIter {
+ walker: self,
+ context,
+ }
+ }
+}
+
+/// A walker and its context wrapped into an iterator.
+#[derive(Clone, Debug)]
+pub struct WalkerIter<W, C> {
+ walker: W,
+ context: C,
+}
+
+impl<W, C> WalkerIter<W, C>
+where
+ W: Walker<C>,
+ C: Clone,
+{
+ pub fn context(&self) -> C {
+ self.context.clone()
+ }
+
+ pub fn inner_ref(&self) -> &W {
+ &self.walker
+ }
+
+ pub fn inner_mut(&mut self) -> &mut W {
+ &mut self.walker
+ }
+}
+
+impl<W, C> Iterator for WalkerIter<W, C>
+where
+ W: Walker<C>,
+ C: Clone,
+{
+ type Item = W::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.walker.walk_next(self.context.clone())
+ }
+}
+
+impl<'a, C, W: ?Sized> Walker<C> for &'a mut W
+where
+ W: Walker<C>,
+{
+ type Item = W::Item;
+ fn walk_next(&mut self, context: C) -> Option<Self::Item> {
+ (**self).walk_next(context)
+ }
+}
+
+impl<G> Walker<G> for Dfs<G::NodeId, G::Map>
+where
+ G: IntoNeighbors + Visitable,
+{
+ type Item = G::NodeId;
+ fn walk_next(&mut self, context: G) -> Option<Self::Item> {
+ self.next(context)
+ }
+}
+
+impl<G> Walker<G> for DfsPostOrder<G::NodeId, G::Map>
+where
+ G: IntoNeighbors + Visitable,
+{
+ type Item = G::NodeId;
+ fn walk_next(&mut self, context: G) -> Option<Self::Item> {
+ self.next(context)
+ }
+}
+
+impl<G> Walker<G> for Bfs<G::NodeId, G::Map>
+where
+ G: IntoNeighbors + Visitable,
+{
+ type Item = G::NodeId;
+ fn walk_next(&mut self, context: G) -> Option<Self::Item> {
+ self.next(context)
+ }
+}
+
+impl<G> Walker<G> for Topo<G::NodeId, G::Map>
+where
+ G: IntoNeighborsDirected + Visitable,
+{
+ type Item = G::NodeId;
+ fn walk_next(&mut self, context: G) -> Option<Self::Item> {
+ self.next(context)
+ }
+}