summaryrefslogtreecommitdiffstats
path: root/vendor/petgraph/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/petgraph/src
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/petgraph/src')
-rw-r--r--vendor/petgraph/src/algo/dominators.rs284
-rw-r--r--vendor/petgraph/src/algo/mod.rs879
-rw-r--r--vendor/petgraph/src/astar.rs175
-rw-r--r--vendor/petgraph/src/csr.rs985
-rw-r--r--vendor/petgraph/src/data.rs474
-rw-r--r--vendor/petgraph/src/dijkstra.rs122
-rw-r--r--vendor/petgraph/src/dot.rs330
-rw-r--r--vendor/petgraph/src/generate.rs133
-rw-r--r--vendor/petgraph/src/graph_impl/frozen.rs96
-rw-r--r--vendor/petgraph/src/graph_impl/mod.rs2172
-rw-r--r--vendor/petgraph/src/graph_impl/serialization.rs345
-rw-r--r--vendor/petgraph/src/graph_impl/stable_graph/mod.rs1817
-rw-r--r--vendor/petgraph/src/graph_impl/stable_graph/serialization.rs296
-rw-r--r--vendor/petgraph/src/graphmap.rs947
-rw-r--r--vendor/petgraph/src/isomorphism.rs525
-rw-r--r--vendor/petgraph/src/iter_format.rs102
-rw-r--r--vendor/petgraph/src/iter_utils.rs32
-rw-r--r--vendor/petgraph/src/lib.rs308
-rw-r--r--vendor/petgraph/src/macros.rs11
-rw-r--r--vendor/petgraph/src/matrix_graph.rs1671
-rw-r--r--vendor/petgraph/src/prelude.rs21
-rw-r--r--vendor/petgraph/src/quickcheck.rs216
-rw-r--r--vendor/petgraph/src/scored.rs52
-rw-r--r--vendor/petgraph/src/serde_utils.rs95
-rw-r--r--vendor/petgraph/src/simple_paths.rs163
-rw-r--r--vendor/petgraph/src/traits_graph.rs73
-rw-r--r--vendor/petgraph/src/unionfind.rs146
-rw-r--r--vendor/petgraph/src/util.rs25
-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
34 files changed, 14893 insertions, 0 deletions
diff --git a/vendor/petgraph/src/algo/dominators.rs b/vendor/petgraph/src/algo/dominators.rs
new file mode 100644
index 000000000..c3cd1c34f
--- /dev/null
+++ b/vendor/petgraph/src/algo/dominators.rs
@@ -0,0 +1,284 @@
+//! Compute dominators of a control-flow graph.
+//!
+//! # The Dominance Relation
+//!
+//! In a directed graph with a root node **R**, a node **A** is said to *dominate* a
+//! node **B** iff every path from **R** to **B** contains **A**.
+//!
+//! The node **A** is said to *strictly dominate* the node **B** iff **A** dominates
+//! **B** and **A ≠ B**.
+//!
+//! The node **A** is said to be the *immediate dominator* of a node **B** iff it
+//! strictly dominates **B** and there does not exist any node **C** where **A**
+//! dominates **C** and **C** dominates **B**.
+
+use std::cmp::Ordering;
+use std::collections::{HashMap, HashSet};
+use std::hash::Hash;
+
+use crate::visit::{DfsPostOrder, GraphBase, IntoNeighbors, Visitable, Walker};
+
+/// The dominance relation for some graph and root.
+#[derive(Debug, Clone)]
+pub struct Dominators<N>
+where
+ N: Copy + Eq + Hash,
+{
+ root: N,
+ dominators: HashMap<N, N>,
+}
+
+impl<N> Dominators<N>
+where
+ N: Copy + Eq + Hash,
+{
+ /// Get the root node used to construct these dominance relations.
+ pub fn root(&self) -> N {
+ self.root
+ }
+
+ /// Get the immediate dominator of the given node.
+ ///
+ /// Returns `None` for any node that is not reachable from the root, and for
+ /// the root itself.
+ pub fn immediate_dominator(&self, node: N) -> Option<N> {
+ if node == self.root {
+ None
+ } else {
+ self.dominators.get(&node).cloned()
+ }
+ }
+
+ /// Iterate over the given node's strict dominators.
+ ///
+ /// If the given node is not reachable from the root, then `None` is
+ /// returned.
+ pub fn strict_dominators(&self, node: N) -> Option<DominatorsIter<N>> {
+ if self.dominators.contains_key(&node) {
+ Some(DominatorsIter {
+ dominators: self,
+ node: self.immediate_dominator(node),
+ })
+ } else {
+ None
+ }
+ }
+
+ /// Iterate over all of the given node's dominators (including the given
+ /// node itself).
+ ///
+ /// If the given node is not reachable from the root, then `None` is
+ /// returned.
+ pub fn dominators(&self, node: N) -> Option<DominatorsIter<N>> {
+ if self.dominators.contains_key(&node) {
+ Some(DominatorsIter {
+ dominators: self,
+ node: Some(node),
+ })
+ } else {
+ None
+ }
+ }
+}
+
+/// Iterator for a node's dominators.
+pub struct DominatorsIter<'a, N>
+where
+ N: 'a + Copy + Eq + Hash,
+{
+ dominators: &'a Dominators<N>,
+ node: Option<N>,
+}
+
+impl<'a, N> Iterator for DominatorsIter<'a, N>
+where
+ N: 'a + Copy + Eq + Hash,
+{
+ type Item = N;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let next = self.node.take();
+ if let Some(next) = next {
+ self.node = self.dominators.immediate_dominator(next);
+ }
+ next
+ }
+}
+
+/// The undefined dominator sentinel, for when we have not yet discovered a
+/// node's dominator.
+const UNDEFINED: usize = ::std::usize::MAX;
+
+/// This is an implementation of the engineered ["Simple, Fast Dominance
+/// Algorithm"][0] discovered by Cooper et al.
+///
+/// This algorithm is **O(|V|²)**, and therefore has slower theoretical running time
+/// than the Lengauer-Tarjan algorithm (which is **O(|E| log |V|)**. However,
+/// Cooper et al found it to be faster in practice on control flow graphs of up
+/// to ~30,000 vertices.
+///
+/// [0]: http://www.cs.rice.edu/~keith/EMBED/dom.pdf
+pub fn simple_fast<G>(graph: G, root: G::NodeId) -> Dominators<G::NodeId>
+where
+ G: IntoNeighbors + Visitable,
+ <G as GraphBase>::NodeId: Eq + Hash,
+{
+ let (post_order, predecessor_sets) = simple_fast_post_order(graph, root);
+ let length = post_order.len();
+ debug_assert!(length > 0);
+ debug_assert!(post_order.last() == Some(&root));
+
+ // From here on out we use indices into `post_order` instead of actual
+ // `NodeId`s wherever possible. This greatly improves the performance of
+ // this implementation, but we have to pay a little bit of upfront cost to
+ // convert our data structures to play along first.
+
+ // Maps a node to its index into `post_order`.
+ let node_to_post_order_idx: HashMap<_, _> = post_order
+ .iter()
+ .enumerate()
+ .map(|(idx, &node)| (node, idx))
+ .collect();
+
+ // Maps a node's `post_order` index to its set of predecessors's indices
+ // into `post_order` (as a vec).
+ let idx_to_predecessor_vec =
+ predecessor_sets_to_idx_vecs(&post_order, &node_to_post_order_idx, predecessor_sets);
+
+ let mut dominators = vec![UNDEFINED; length];
+ dominators[length - 1] = length - 1;
+
+ let mut changed = true;
+ while changed {
+ changed = false;
+
+ // Iterate in reverse post order, skipping the root.
+
+ for idx in (0..length - 1).rev() {
+ debug_assert!(post_order[idx] != root);
+
+ // Take the intersection of every predecessor's dominator set; that
+ // is the current best guess at the immediate dominator for this
+ // node.
+
+ let new_idom_idx = {
+ let mut predecessors = idx_to_predecessor_vec[idx]
+ .iter()
+ .filter(|&&p| dominators[p] != UNDEFINED);
+ let new_idom_idx = predecessors.next().expect(
+ "Because the root is initialized to dominate itself, and is the \
+ first node in every path, there must exist a predecessor to this \
+ node that also has a dominator",
+ );
+ predecessors.fold(*new_idom_idx, |new_idom_idx, &predecessor_idx| {
+ intersect(&dominators, new_idom_idx, predecessor_idx)
+ })
+ };
+
+ debug_assert!(new_idom_idx < length);
+
+ if new_idom_idx != dominators[idx] {
+ dominators[idx] = new_idom_idx;
+ changed = true;
+ }
+ }
+ }
+
+ // All done! Translate the indices back into proper `G::NodeId`s.
+
+ debug_assert!(!dominators.iter().any(|&dom| dom == UNDEFINED));
+
+ Dominators {
+ root,
+ dominators: dominators
+ .into_iter()
+ .enumerate()
+ .map(|(idx, dom_idx)| (post_order[idx], post_order[dom_idx]))
+ .collect(),
+ }
+}
+
+fn intersect(dominators: &[usize], mut finger1: usize, mut finger2: usize) -> usize {
+ loop {
+ match finger1.cmp(&finger2) {
+ Ordering::Less => finger1 = dominators[finger1],
+ Ordering::Greater => finger2 = dominators[finger2],
+ Ordering::Equal => return finger1,
+ }
+ }
+}
+
+fn predecessor_sets_to_idx_vecs<N>(
+ post_order: &[N],
+ node_to_post_order_idx: &HashMap<N, usize>,
+ mut predecessor_sets: HashMap<N, HashSet<N>>,
+) -> Vec<Vec<usize>>
+where
+ N: Copy + Eq + Hash,
+{
+ post_order
+ .iter()
+ .map(|node| {
+ predecessor_sets
+ .remove(node)
+ .map(|predecessors| {
+ predecessors
+ .into_iter()
+ .map(|p| *node_to_post_order_idx.get(&p).unwrap())
+ .collect()
+ })
+ .unwrap_or_else(Vec::new)
+ })
+ .collect()
+}
+
+fn simple_fast_post_order<G>(
+ graph: G,
+ root: G::NodeId,
+) -> (Vec<G::NodeId>, HashMap<G::NodeId, HashSet<G::NodeId>>)
+where
+ G: IntoNeighbors + Visitable,
+ <G as GraphBase>::NodeId: Eq + Hash,
+{
+ let mut post_order = vec![];
+ let mut predecessor_sets = HashMap::new();
+
+ for node in DfsPostOrder::new(graph, root).iter(graph) {
+ post_order.push(node);
+
+ for successor in graph.neighbors(node) {
+ predecessor_sets
+ .entry(successor)
+ .or_insert_with(HashSet::new)
+ .insert(node);
+ }
+ }
+
+ (post_order, predecessor_sets)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_iter_dominators() {
+ let doms: Dominators<u32> = Dominators {
+ root: 0,
+ dominators: [(2, 1), (1, 0), (0, 0)].iter().cloned().collect(),
+ };
+
+ let all_doms: Vec<_> = doms.dominators(2).unwrap().collect();
+ assert_eq!(vec![2, 1, 0], all_doms);
+
+ assert_eq!(None::<()>, doms.dominators(99).map(|_| unreachable!()));
+
+ let strict_doms: Vec<_> = doms.strict_dominators(2).unwrap().collect();
+ assert_eq!(vec![1, 0], strict_doms);
+
+ assert_eq!(
+ None::<()>,
+ doms.strict_dominators(99).map(|_| unreachable!())
+ );
+ }
+}
diff --git a/vendor/petgraph/src/algo/mod.rs b/vendor/petgraph/src/algo/mod.rs
new file mode 100644
index 000000000..c9c5a469d
--- /dev/null
+++ b/vendor/petgraph/src/algo/mod.rs
@@ -0,0 +1,879 @@
+//! Graph algorithms.
+//!
+//! It is a goal to gradually migrate the algorithms to be based on graph traits
+//! so that they are generally applicable. For now, some of these still require
+//! the `Graph` type.
+
+pub mod dominators;
+
+use std::cmp::min;
+use std::collections::{BinaryHeap, HashMap};
+
+use crate::prelude::*;
+
+use super::graph::IndexType;
+use super::unionfind::UnionFind;
+use super::visit::{
+ GraphBase, GraphRef, IntoEdgeReferences, IntoEdges, IntoNeighbors, IntoNeighborsDirected,
+ IntoNodeIdentifiers, NodeCompactIndexable, NodeCount, NodeIndexable, Reversed, VisitMap,
+ Visitable,
+};
+use super::EdgeType;
+use crate::data::Element;
+use crate::scored::MinScored;
+use crate::visit::Walker;
+use crate::visit::{Data, IntoNodeReferences, NodeRef};
+
+pub use super::astar::astar;
+pub use super::dijkstra::dijkstra;
+pub use super::isomorphism::{is_isomorphic, is_isomorphic_matching};
+pub use super::simple_paths::all_simple_paths;
+
+/// \[Generic\] Return the number of connected components of the graph.
+///
+/// For a directed graph, this is the *weakly* connected components.
+/// # Example
+/// ```rust
+/// use petgraph::Graph;
+/// use petgraph::algo::connected_components;
+/// use petgraph::prelude::*;
+///
+/// let mut graph : Graph<(),(),Directed>= Graph::new();
+/// let a = graph.add_node(()); // node with no weight
+/// let b = graph.add_node(());
+/// let c = graph.add_node(());
+/// let d = graph.add_node(());
+/// let e = graph.add_node(());
+/// let f = graph.add_node(());
+/// let g = graph.add_node(());
+/// let h = graph.add_node(());
+///
+/// graph.extend_with_edges(&[
+/// (a, b),
+/// (b, c),
+/// (c, d),
+/// (d, a),
+/// (e, f),
+/// (f, g),
+/// (g, h),
+/// (h, e)
+/// ]);
+/// // a ----> b e ----> f
+/// // ^ | ^ |
+/// // | v | v
+/// // d <---- c h <---- g
+///
+/// assert_eq!(connected_components(&graph),2);
+/// graph.add_edge(b,e,());
+/// assert_eq!(connected_components(&graph),1);
+/// ```
+pub fn connected_components<G>(g: G) -> usize
+where
+ G: NodeCompactIndexable + IntoEdgeReferences,
+{
+ let mut vertex_sets = UnionFind::new(g.node_bound());
+ for edge in g.edge_references() {
+ let (a, b) = (edge.source(), edge.target());
+
+ // union the two vertices of the edge
+ vertex_sets.union(g.to_index(a), g.to_index(b));
+ }
+ let mut labels = vertex_sets.into_labeling();
+ labels.sort();
+ labels.dedup();
+ labels.len()
+}
+
+/// \[Generic\] Return `true` if the input graph contains a cycle.
+///
+/// Always treats the input graph as if undirected.
+pub fn is_cyclic_undirected<G>(g: G) -> bool
+where
+ G: NodeIndexable + IntoEdgeReferences,
+{
+ let mut edge_sets = UnionFind::new(g.node_bound());
+ for edge in g.edge_references() {
+ let (a, b) = (edge.source(), edge.target());
+
+ // union the two vertices of the edge
+ // -- if they were already the same, then we have a cycle
+ if !edge_sets.union(g.to_index(a), g.to_index(b)) {
+ return true;
+ }
+ }
+ false
+}
+
+/// \[Generic\] Perform a topological sort of a directed graph.
+///
+/// If the graph was acyclic, return a vector of nodes in topological order:
+/// each node is ordered before its successors.
+/// Otherwise, it will return a `Cycle` error. Self loops are also cycles.
+///
+/// To handle graphs with cycles, use the scc algorithms or `DfsPostOrder`
+/// instead of this function.
+///
+/// If `space` is not `None`, it is used instead of creating a new workspace for
+/// graph traversal. The implementation is iterative.
+pub fn toposort<G>(
+ g: G,
+ space: Option<&mut DfsSpace<G::NodeId, G::Map>>,
+) -> Result<Vec<G::NodeId>, Cycle<G::NodeId>>
+where
+ G: IntoNeighborsDirected + IntoNodeIdentifiers + Visitable,
+{
+ // based on kosaraju scc
+ with_dfs(g, space, |dfs| {
+ dfs.reset(g);
+ let mut finished = g.visit_map();
+
+ let mut finish_stack = Vec::new();
+ for i in g.node_identifiers() {
+ if dfs.discovered.is_visited(&i) {
+ continue;
+ }
+ dfs.stack.push(i);
+ while let Some(&nx) = dfs.stack.last() {
+ if dfs.discovered.visit(nx) {
+ // First time visiting `nx`: Push neighbors, don't pop `nx`
+ for succ in g.neighbors(nx) {
+ if succ == nx {
+ // self cycle
+ return Err(Cycle(nx));
+ }
+ if !dfs.discovered.is_visited(&succ) {
+ dfs.stack.push(succ);
+ }
+ }
+ } else {
+ dfs.stack.pop();
+ if finished.visit(nx) {
+ // Second time: All reachable nodes must have been finished
+ finish_stack.push(nx);
+ }
+ }
+ }
+ }
+ finish_stack.reverse();
+
+ dfs.reset(g);
+ for &i in &finish_stack {
+ dfs.move_to(i);
+ let mut cycle = false;
+ while let Some(j) = dfs.next(Reversed(g)) {
+ if cycle {
+ return Err(Cycle(j));
+ }
+ cycle = true;
+ }
+ }
+
+ Ok(finish_stack)
+ })
+}
+
+/// \[Generic\] Return `true` if the input directed graph contains a cycle.
+///
+/// This implementation is recursive; use `toposort` if an alternative is
+/// needed.
+pub fn is_cyclic_directed<G>(g: G) -> bool
+where
+ G: IntoNodeIdentifiers + IntoNeighbors + Visitable,
+{
+ use crate::visit::{depth_first_search, DfsEvent};
+
+ depth_first_search(g, g.node_identifiers(), |event| match event {
+ DfsEvent::BackEdge(_, _) => Err(()),
+ _ => Ok(()),
+ })
+ .is_err()
+}
+
+type DfsSpaceType<G> = DfsSpace<<G as GraphBase>::NodeId, <G as Visitable>::Map>;
+
+/// Workspace for a graph traversal.
+#[derive(Clone, Debug)]
+pub struct DfsSpace<N, VM> {
+ dfs: Dfs<N, VM>,
+}
+
+impl<N, VM> DfsSpace<N, VM>
+where
+ N: Copy + PartialEq,
+ VM: VisitMap<N>,
+{
+ pub fn new<G>(g: G) -> Self
+ where
+ G: GraphRef + Visitable<NodeId = N, Map = VM>,
+ {
+ DfsSpace { dfs: Dfs::empty(g) }
+ }
+}
+
+impl<N, VM> Default for DfsSpace<N, VM>
+where
+ VM: VisitMap<N> + Default,
+{
+ fn default() -> Self {
+ DfsSpace {
+ dfs: Dfs {
+ stack: <_>::default(),
+ discovered: <_>::default(),
+ },
+ }
+ }
+}
+
+/// Create a Dfs if it's needed
+fn with_dfs<G, F, R>(g: G, space: Option<&mut DfsSpaceType<G>>, f: F) -> R
+where
+ G: GraphRef + Visitable,
+ F: FnOnce(&mut Dfs<G::NodeId, G::Map>) -> R,
+{
+ let mut local_visitor;
+ let dfs = if let Some(v) = space {
+ &mut v.dfs
+ } else {
+ local_visitor = Dfs::empty(g);
+ &mut local_visitor
+ };
+ f(dfs)
+}
+
+/// \[Generic\] Check if there exists a path starting at `from` and reaching `to`.
+///
+/// If `from` and `to` are equal, this function returns true.
+///
+/// If `space` is not `None`, it is used instead of creating a new workspace for
+/// graph traversal.
+pub fn has_path_connecting<G>(
+ g: G,
+ from: G::NodeId,
+ to: G::NodeId,
+ space: Option<&mut DfsSpace<G::NodeId, G::Map>>,
+) -> bool
+where
+ G: IntoNeighbors + Visitable,
+{
+ with_dfs(g, space, |dfs| {
+ dfs.reset(g);
+ dfs.move_to(from);
+ dfs.iter(g).any(|x| x == to)
+ })
+}
+
+/// Renamed to `kosaraju_scc`.
+#[deprecated(note = "renamed to kosaraju_scc")]
+pub fn scc<G>(g: G) -> Vec<Vec<G::NodeId>>
+where
+ G: IntoNeighborsDirected + Visitable + IntoNodeIdentifiers,
+{
+ kosaraju_scc(g)
+}
+
+/// \[Generic\] Compute the *strongly connected components* using [Kosaraju's algorithm][1].
+///
+/// [1]: https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
+///
+/// Return a vector where each element is a strongly connected component (scc).
+/// The order of node ids within each scc is arbitrary, but the order of
+/// the sccs is their postorder (reverse topological sort).
+///
+/// For an undirected graph, the sccs are simply the connected components.
+///
+/// This implementation is iterative and does two passes over the nodes.
+pub fn kosaraju_scc<G>(g: G) -> Vec<Vec<G::NodeId>>
+where
+ G: IntoNeighborsDirected + Visitable + IntoNodeIdentifiers,
+{
+ let mut dfs = DfsPostOrder::empty(g);
+
+ // First phase, reverse dfs pass, compute finishing times.
+ // http://stackoverflow.com/a/26780899/161659
+ let mut finish_order = Vec::with_capacity(0);
+ for i in g.node_identifiers() {
+ if dfs.discovered.is_visited(&i) {
+ continue;
+ }
+
+ dfs.move_to(i);
+ while let Some(nx) = dfs.next(Reversed(g)) {
+ finish_order.push(nx);
+ }
+ }
+
+ let mut dfs = Dfs::from_parts(dfs.stack, dfs.discovered);
+ dfs.reset(g);
+ let mut sccs = Vec::new();
+
+ // Second phase
+ // Process in decreasing finishing time order
+ for i in finish_order.into_iter().rev() {
+ if dfs.discovered.is_visited(&i) {
+ continue;
+ }
+ // Move to the leader node `i`.
+ dfs.move_to(i);
+ let mut scc = Vec::new();
+ while let Some(nx) = dfs.next(g) {
+ scc.push(nx);
+ }
+ sccs.push(scc);
+ }
+ sccs
+}
+
+/// \[Generic\] Compute the *strongly connected components* using [Tarjan's algorithm][1].
+///
+/// [1]: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
+///
+/// Return a vector where each element is a strongly connected component (scc).
+/// The order of node ids within each scc is arbitrary, but the order of
+/// the sccs is their postorder (reverse topological sort).
+///
+/// For an undirected graph, the sccs are simply the connected components.
+///
+/// This implementation is recursive and does one pass over the nodes.
+pub fn tarjan_scc<G>(g: G) -> Vec<Vec<G::NodeId>>
+where
+ G: IntoNodeIdentifiers + IntoNeighbors + NodeIndexable,
+{
+ #[derive(Copy, Clone, Debug)]
+ struct NodeData {
+ index: Option<usize>,
+ lowlink: usize,
+ on_stack: bool,
+ }
+
+ #[derive(Debug)]
+ struct Data<'a, G>
+ where
+ G: NodeIndexable,
+ G::NodeId: 'a,
+ {
+ index: usize,
+ nodes: Vec<NodeData>,
+ stack: Vec<G::NodeId>,
+ sccs: &'a mut Vec<Vec<G::NodeId>>,
+ }
+
+ fn scc_visit<G>(v: G::NodeId, g: G, data: &mut Data<G>)
+ where
+ G: IntoNeighbors + NodeIndexable,
+ {
+ macro_rules! node {
+ ($node:expr) => {
+ data.nodes[g.to_index($node)]
+ };
+ }
+
+ if node![v].index.is_some() {
+ // already visited
+ return;
+ }
+
+ let v_index = data.index;
+ node![v].index = Some(v_index);
+ node![v].lowlink = v_index;
+ node![v].on_stack = true;
+ data.stack.push(v);
+ data.index += 1;
+
+ for w in g.neighbors(v) {
+ match node![w].index {
+ None => {
+ scc_visit(w, g, data);
+ node![v].lowlink = min(node![v].lowlink, node![w].lowlink);
+ }
+ Some(w_index) => {
+ if node![w].on_stack {
+ // Successor w is in stack S and hence in the current SCC
+ let v_lowlink = &mut node![v].lowlink;
+ *v_lowlink = min(*v_lowlink, w_index);
+ }
+ }
+ }
+ }
+
+ // If v is a root node, pop the stack and generate an SCC
+ if let Some(v_index) = node![v].index {
+ if node![v].lowlink == v_index {
+ let mut cur_scc = Vec::new();
+ loop {
+ let w = data.stack.pop().unwrap();
+ node![w].on_stack = false;
+ cur_scc.push(w);
+ if g.to_index(w) == g.to_index(v) {
+ break;
+ }
+ }
+ data.sccs.push(cur_scc);
+ }
+ }
+ }
+
+ let mut sccs = Vec::new();
+ {
+ let map = vec![
+ NodeData {
+ index: None,
+ lowlink: !0,
+ on_stack: false
+ };
+ g.node_bound()
+ ];
+
+ let mut data = Data {
+ index: 0,
+ nodes: map,
+ stack: Vec::new(),
+ sccs: &mut sccs,
+ };
+
+ for n in g.node_identifiers() {
+ scc_visit(n, g, &mut data);
+ }
+ }
+ sccs
+}
+
+/// [Graph] Condense every strongly connected component into a single node and return the result.
+///
+/// If `make_acyclic` is true, self-loops and multi edges are ignored, guaranteeing that
+/// the output is acyclic.
+/// # Example
+/// ```rust
+/// use petgraph::Graph;
+/// use petgraph::algo::condensation;
+/// use petgraph::prelude::*;
+///
+/// let mut graph : Graph<(),(),Directed> = Graph::new();
+/// let a = graph.add_node(()); // node with no weight
+/// let b = graph.add_node(());
+/// let c = graph.add_node(());
+/// let d = graph.add_node(());
+/// let e = graph.add_node(());
+/// let f = graph.add_node(());
+/// let g = graph.add_node(());
+/// let h = graph.add_node(());
+///
+/// graph.extend_with_edges(&[
+/// (a, b),
+/// (b, c),
+/// (c, d),
+/// (d, a),
+/// (b, e),
+/// (e, f),
+/// (f, g),
+/// (g, h),
+/// (h, e)
+/// ]);
+///
+/// // a ----> b ----> e ----> f
+/// // ^ | ^ |
+/// // | v | v
+/// // d <---- c h <---- g
+///
+/// let condensed_graph = condensation(graph,false);
+/// let A = NodeIndex::new(0);
+/// let B = NodeIndex::new(1);
+/// assert_eq!(condensed_graph.node_count(), 2);
+/// assert_eq!(condensed_graph.edge_count(), 9);
+/// assert_eq!(condensed_graph.neighbors(A).collect::<Vec<_>>(), vec![A, A, A, A]);
+/// assert_eq!(condensed_graph.neighbors(B).collect::<Vec<_>>(), vec![A, B, B, B, B]);
+/// ```
+/// If `make_acyclic` is true, self-loops and multi edges are ignored:
+///
+/// ```rust
+/// # use petgraph::Graph;
+/// # use petgraph::algo::condensation;
+/// # use petgraph::prelude::*;
+/// #
+/// # let mut graph : Graph<(),(),Directed> = Graph::new();
+/// # let a = graph.add_node(()); // node with no weight
+/// # let b = graph.add_node(());
+/// # let c = graph.add_node(());
+/// # let d = graph.add_node(());
+/// # let e = graph.add_node(());
+/// # let f = graph.add_node(());
+/// # let g = graph.add_node(());
+/// # let h = graph.add_node(());
+/// #
+/// # graph.extend_with_edges(&[
+/// # (a, b),
+/// # (b, c),
+/// # (c, d),
+/// # (d, a),
+/// # (b, e),
+/// # (e, f),
+/// # (f, g),
+/// # (g, h),
+/// # (h, e)
+/// # ]);
+/// let acyclic_condensed_graph = condensation(graph, true);
+/// let A = NodeIndex::new(0);
+/// let B = NodeIndex::new(1);
+/// assert_eq!(acyclic_condensed_graph.node_count(), 2);
+/// assert_eq!(acyclic_condensed_graph.edge_count(), 1);
+/// assert_eq!(acyclic_condensed_graph.neighbors(B).collect::<Vec<_>>(), vec![A]);
+/// ```
+pub fn condensation<N, E, Ty, Ix>(
+ g: Graph<N, E, Ty, Ix>,
+ make_acyclic: bool,
+) -> Graph<Vec<N>, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ let sccs = kosaraju_scc(&g);
+ let mut condensed: Graph<Vec<N>, E, Ty, Ix> = Graph::with_capacity(sccs.len(), g.edge_count());
+
+ // Build a map from old indices to new ones.
+ let mut node_map = vec![NodeIndex::end(); g.node_count()];
+ for comp in sccs {
+ let new_nix = condensed.add_node(Vec::new());
+ for nix in comp {
+ node_map[nix.index()] = new_nix;
+ }
+ }
+
+ // Consume nodes and edges of the old graph and insert them into the new one.
+ let (nodes, edges) = g.into_nodes_edges();
+ for (nix, node) in nodes.into_iter().enumerate() {
+ condensed[node_map[nix]].push(node.weight);
+ }
+ for edge in edges {
+ let source = node_map[edge.source().index()];
+ let target = node_map[edge.target().index()];
+ if make_acyclic {
+ if source != target {
+ condensed.update_edge(source, target, edge.weight);
+ }
+ } else {
+ condensed.add_edge(source, target, edge.weight);
+ }
+ }
+ condensed
+}
+
+/// \[Generic\] Compute a *minimum spanning tree* of a graph.
+///
+/// The input graph is treated as if undirected.
+///
+/// Using Kruskal's algorithm with runtime **O(|E| log |E|)**. We actually
+/// return a minimum spanning forest, i.e. a minimum spanning tree for each connected
+/// component of the graph.
+///
+/// The resulting graph has all the vertices of the input graph (with identical node indices),
+/// and **|V| - c** edges, where **c** is the number of connected components in `g`.
+///
+/// Use `from_elements` to create a graph from the resulting iterator.
+pub fn min_spanning_tree<G>(g: G) -> MinSpanningTree<G>
+where
+ G::NodeWeight: Clone,
+ G::EdgeWeight: Clone + PartialOrd,
+ G: IntoNodeReferences + IntoEdgeReferences + NodeIndexable,
+{
+ // Initially each vertex is its own disjoint subgraph, track the connectedness
+ // of the pre-MST with a union & find datastructure.
+ let subgraphs = UnionFind::new(g.node_bound());
+
+ let edges = g.edge_references();
+ let mut sort_edges = BinaryHeap::with_capacity(edges.size_hint().0);
+ for edge in edges {
+ sort_edges.push(MinScored(
+ edge.weight().clone(),
+ (edge.source(), edge.target()),
+ ));
+ }
+
+ MinSpanningTree {
+ graph: g,
+ node_ids: Some(g.node_references()),
+ subgraphs,
+ sort_edges,
+ node_map: HashMap::new(),
+ node_count: 0,
+ }
+}
+
+/// An iterator producing a minimum spanning forest of a graph.
+pub struct MinSpanningTree<G>
+where
+ G: Data + IntoNodeReferences,
+{
+ graph: G,
+ node_ids: Option<G::NodeReferences>,
+ subgraphs: UnionFind<usize>,
+ sort_edges: BinaryHeap<MinScored<G::EdgeWeight, (G::NodeId, G::NodeId)>>,
+ node_map: HashMap<usize, usize>,
+ node_count: usize,
+}
+
+impl<G> Iterator for MinSpanningTree<G>
+where
+ G: IntoNodeReferences + NodeIndexable,
+ G::NodeWeight: Clone,
+ G::EdgeWeight: PartialOrd,
+{
+ type Item = Element<G::NodeWeight, G::EdgeWeight>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let g = self.graph;
+ if let Some(ref mut iter) = self.node_ids {
+ if let Some(node) = iter.next() {
+ self.node_map.insert(g.to_index(node.id()), self.node_count);
+ self.node_count += 1;
+ return Some(Element::Node {
+ weight: node.weight().clone(),
+ });
+ }
+ }
+ self.node_ids = None;
+
+ // Kruskal's algorithm.
+ // Algorithm is this:
+ //
+ // 1. Create a pre-MST with all the vertices and no edges.
+ // 2. Repeat:
+ //
+ // a. Remove the shortest edge from the original graph.
+ // b. If the edge connects two disjoint trees in the pre-MST,
+ // add the edge.
+ while let Some(MinScored(score, (a, b))) = self.sort_edges.pop() {
+ // check if the edge would connect two disjoint parts
+ let (a_index, b_index) = (g.to_index(a), g.to_index(b));
+ if self.subgraphs.union(a_index, b_index) {
+ let (&a_order, &b_order) =
+ match (self.node_map.get(&a_index), self.node_map.get(&b_index)) {
+ (Some(a_id), Some(b_id)) => (a_id, b_id),
+ _ => panic!("Edge references unknown node"),
+ };
+ return Some(Element::Edge {
+ source: a_order,
+ target: b_order,
+ weight: score,
+ });
+ }
+ }
+ None
+ }
+}
+
+/// An algorithm error: a cycle was found in the graph.
+#[derive(Clone, Debug, PartialEq)]
+pub struct Cycle<N>(N);
+
+impl<N> Cycle<N> {
+ /// Return a node id that participates in the cycle
+ pub fn node_id(&self) -> N
+ where
+ N: Copy,
+ {
+ self.0
+ }
+}
+/// An algorithm error: a cycle of negative weights was found in the graph.
+#[derive(Clone, Debug, PartialEq)]
+pub struct NegativeCycle(());
+
+/// \[Generic\] Compute shortest paths from node `source` to all other.
+///
+/// Using the [Bellman–Ford algorithm][bf]; negative edge costs are
+/// permitted, but the graph must not have a cycle of negative weights
+/// (in that case it will return an error).
+///
+/// On success, return one vec with path costs, and another one which points
+/// out the predecessor of a node along a shortest path. The vectors
+/// are indexed by the graph's node indices.
+///
+/// [bf]: https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm
+///
+/// # Example
+/// ```rust
+/// use petgraph::Graph;
+/// use petgraph::algo::bellman_ford;
+/// use petgraph::prelude::*;
+///
+/// let mut g = Graph::new();
+/// let a = g.add_node(()); // node with no weight
+/// let b = g.add_node(());
+/// let c = g.add_node(());
+/// let d = g.add_node(());
+/// let e = g.add_node(());
+/// let f = g.add_node(());
+/// g.extend_with_edges(&[
+/// (0, 1, 2.0),
+/// (0, 3, 4.0),
+/// (1, 2, 1.0),
+/// (1, 5, 7.0),
+/// (2, 4, 5.0),
+/// (4, 5, 1.0),
+/// (3, 4, 1.0),
+/// ]);
+///
+/// // Graph represented with the weight of each edge
+/// //
+/// // 2 1
+/// // a ----- b ----- c
+/// // | 4 | 7 |
+/// // d f | 5
+/// // | 1 | 1 |
+/// // \------ e ------/
+///
+/// let path = bellman_ford(&g, a);
+/// assert_eq!(path, Ok((vec![0.0 , 2.0, 3.0, 4.0, 5.0, 6.0],
+/// vec![None, Some(a),Some(b),Some(a), Some(d), Some(e)]
+/// ))
+/// );
+/// // Node f (indice 5) can be reach from a with a path costing 6.
+/// // Predecessor of f is Some(e) which predecessor is Some(d) which predecessor is Some(a).
+/// // Thus the path from a to f is a <-> d <-> e <-> f
+///
+/// let graph_with_neg_cycle = Graph::<(), f32, Undirected>::from_edges(&[
+/// (0, 1, -2.0),
+/// (0, 3, -4.0),
+/// (1, 2, -1.0),
+/// (1, 5, -25.0),
+/// (2, 4, -5.0),
+/// (4, 5, -25.0),
+/// (3, 4, -1.0),
+/// ]);
+///
+/// assert!(bellman_ford(&graph_with_neg_cycle, NodeIndex::new(0)).is_err());
+/// ```
+pub fn bellman_ford<G>(
+ g: G,
+ source: G::NodeId,
+) -> Result<(Vec<G::EdgeWeight>, Vec<Option<G::NodeId>>), NegativeCycle>
+where
+ G: NodeCount + IntoNodeIdentifiers + IntoEdges + NodeIndexable,
+ G::EdgeWeight: FloatMeasure,
+{
+ let mut predecessor = vec![None; g.node_bound()];
+ let mut distance = vec![<_>::infinite(); g.node_bound()];
+
+ let ix = |i| g.to_index(i);
+
+ distance[ix(source)] = <_>::zero();
+ // scan up to |V| - 1 times.
+ for _ in 1..g.node_count() {
+ let mut did_update = false;
+ for i in g.node_identifiers() {
+ for edge in g.edges(i) {
+ let i = edge.source();
+ let j = edge.target();
+ let w = *edge.weight();
+ if distance[ix(i)] + w < distance[ix(j)] {
+ distance[ix(j)] = distance[ix(i)] + w;
+ predecessor[ix(j)] = Some(i);
+ did_update = true;
+ }
+ }
+ }
+ if !did_update {
+ break;
+ }
+ }
+
+ // check for negative weight cycle
+ for i in g.node_identifiers() {
+ for edge in g.edges(i) {
+ let j = edge.target();
+ let w = *edge.weight();
+ if distance[ix(i)] + w < distance[ix(j)] {
+ //println!("neg cycle, detected from {} to {}, weight={}", i, j, w);
+ return Err(NegativeCycle(()));
+ }
+ }
+ }
+
+ Ok((distance, predecessor))
+}
+
+/// Return `true` if the graph is bipartite. A graph is bipartite if it's nodes can be divided into
+/// two disjoint and indepedent sets U and V such that every edge connects U to one in V. This
+/// algorithm implements 2-coloring algorithm based on the BFS algorithm.
+///
+/// Always treats the input graph as if undirected.
+pub fn is_bipartite_undirected<G, N, VM>(g: G, start: N) -> bool
+where
+ G: GraphRef + Visitable<NodeId = N, Map = VM> + IntoNeighbors<NodeId = N>,
+ N: Copy + PartialEq + std::fmt::Debug,
+ VM: VisitMap<N>,
+{
+ let mut red = g.visit_map();
+ red.visit(start);
+ let mut blue = g.visit_map();
+
+ let mut stack = ::std::collections::VecDeque::new();
+ stack.push_front(start);
+
+ while let Some(node) = stack.pop_front() {
+ let is_red = red.is_visited(&node);
+ let is_blue = blue.is_visited(&node);
+
+ assert!(is_red ^ is_blue);
+
+ for neighbour in g.neighbors(node) {
+ let is_neigbour_red = red.is_visited(&neighbour);
+ let is_neigbour_blue = blue.is_visited(&neighbour);
+
+ if (is_red && is_neigbour_red) || (is_blue && is_neigbour_blue) {
+ return false;
+ }
+
+ if !is_neigbour_red && !is_neigbour_blue {
+ //hasn't been visited yet
+
+ match (is_red, is_blue) {
+ (true, false) => {
+ blue.visit(neighbour);
+ }
+ (false, true) => {
+ red.visit(neighbour);
+ }
+ (_, _) => {
+ panic!("Invariant doesn't hold");
+ }
+ }
+
+ stack.push_back(neighbour);
+ }
+ }
+ }
+
+ true
+}
+
+use std::fmt::Debug;
+use std::ops::Add;
+
+/// Associated data that can be used for measures (such as length).
+pub trait Measure: Debug + PartialOrd + Add<Self, Output = Self> + Default + Clone {}
+
+impl<M> Measure for M where M: Debug + PartialOrd + Add<M, Output = M> + Default + Clone {}
+
+/// A floating-point measure.
+pub trait FloatMeasure: Measure + Copy {
+ fn zero() -> Self;
+ fn infinite() -> Self;
+}
+
+impl FloatMeasure for f32 {
+ fn zero() -> Self {
+ 0.
+ }
+ fn infinite() -> Self {
+ 1. / 0.
+ }
+}
+
+impl FloatMeasure for f64 {
+ fn zero() -> Self {
+ 0.
+ }
+ fn infinite() -> Self {
+ 1. / 0.
+ }
+}
diff --git a/vendor/petgraph/src/astar.rs b/vendor/petgraph/src/astar.rs
new file mode 100644
index 000000000..56b3e2eb0
--- /dev/null
+++ b/vendor/petgraph/src/astar.rs
@@ -0,0 +1,175 @@
+use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::collections::{BinaryHeap, HashMap};
+
+use std::hash::Hash;
+
+use super::visit::{EdgeRef, GraphBase, IntoEdges, VisitMap, Visitable};
+use crate::scored::MinScored;
+
+use crate::algo::Measure;
+
+/// \[Generic\] A* shortest path algorithm.
+///
+/// Computes the shortest path from `start` to `finish`, including the total path cost.
+///
+/// `finish` is implicitly given via the `is_goal` callback, which should return `true` if the
+/// given node is the finish node.
+///
+/// The function `edge_cost` should return the cost for a particular edge. Edge costs must be
+/// non-negative.
+///
+/// The function `estimate_cost` should return the estimated cost to the finish for a particular
+/// node. For the algorithm to find the actual shortest path, it should be admissible, meaning that
+/// it should never overestimate the actual cost to get to the nearest goal node. Estimate costs
+/// must also be non-negative.
+///
+/// The graph should be `Visitable` and implement `IntoEdges`.
+///
+/// # Example
+/// ```
+/// use petgraph::Graph;
+/// use petgraph::algo::astar;
+///
+/// let mut g = Graph::new();
+/// let a = g.add_node((0., 0.));
+/// let b = g.add_node((2., 0.));
+/// let c = g.add_node((1., 1.));
+/// let d = g.add_node((0., 2.));
+/// let e = g.add_node((3., 3.));
+/// let f = g.add_node((4., 2.));
+/// g.extend_with_edges(&[
+/// (a, b, 2),
+/// (a, d, 4),
+/// (b, c, 1),
+/// (b, f, 7),
+/// (c, e, 5),
+/// (e, f, 1),
+/// (d, e, 1),
+/// ]);
+///
+/// // Graph represented with the weight of each edge
+/// // Edges with '*' are part of the optimal path.
+/// //
+/// // 2 1
+/// // a ----- b ----- c
+/// // | 4* | 7 |
+/// // d f | 5
+/// // | 1* | 1* |
+/// // \------ e ------/
+///
+/// let path = astar(&g, a, |finish| finish == f, |e| *e.weight(), |_| 0);
+/// assert_eq!(path, Some((6, vec![a, d, e, f])));
+/// ```
+///
+/// Returns the total cost + the path of subsequent `NodeId` from start to finish, if one was
+/// found.
+pub fn astar<G, F, H, K, IsGoal>(
+ graph: G,
+ start: G::NodeId,
+ mut is_goal: IsGoal,
+ mut edge_cost: F,
+ mut estimate_cost: H,
+) -> Option<(K, Vec<G::NodeId>)>
+where
+ G: IntoEdges + Visitable,
+ IsGoal: FnMut(G::NodeId) -> bool,
+ G::NodeId: Eq + Hash,
+ F: FnMut(G::EdgeRef) -> K,
+ H: FnMut(G::NodeId) -> K,
+ K: Measure + Copy,
+{
+ let mut visited = graph.visit_map();
+ let mut visit_next = BinaryHeap::new();
+ let mut scores = HashMap::new();
+ let mut path_tracker = PathTracker::<G>::new();
+
+ let zero_score = K::default();
+ scores.insert(start, zero_score);
+ visit_next.push(MinScored(estimate_cost(start), start));
+
+ while let Some(MinScored(_, node)) = visit_next.pop() {
+ if is_goal(node) {
+ let path = path_tracker.reconstruct_path_to(node);
+ let cost = scores[&node];
+ return Some((cost, path));
+ }
+
+ // Don't visit the same node several times, as the first time it was visited it was using
+ // the shortest available path.
+ if !visited.visit(node) {
+ continue;
+ }
+
+ // This lookup can be unwrapped without fear of panic since the node was necessarily scored
+ // before adding him to `visit_next`.
+ let node_score = scores[&node];
+
+ for edge in graph.edges(node) {
+ let next = edge.target();
+ if visited.is_visited(&next) {
+ continue;
+ }
+
+ let mut next_score = node_score + edge_cost(edge);
+
+ match scores.entry(next) {
+ Occupied(ent) => {
+ let old_score = *ent.get();
+ if next_score < old_score {
+ *ent.into_mut() = next_score;
+ path_tracker.set_predecessor(next, node);
+ } else {
+ next_score = old_score;
+ }
+ }
+ Vacant(ent) => {
+ ent.insert(next_score);
+ path_tracker.set_predecessor(next, node);
+ }
+ }
+
+ let next_estimate_score = next_score + estimate_cost(next);
+ visit_next.push(MinScored(next_estimate_score, next));
+ }
+ }
+
+ None
+}
+
+struct PathTracker<G>
+where
+ G: GraphBase,
+ G::NodeId: Eq + Hash,
+{
+ came_from: HashMap<G::NodeId, G::NodeId>,
+}
+
+impl<G> PathTracker<G>
+where
+ G: GraphBase,
+ G::NodeId: Eq + Hash,
+{
+ fn new() -> PathTracker<G> {
+ PathTracker {
+ came_from: HashMap::new(),
+ }
+ }
+
+ fn set_predecessor(&mut self, node: G::NodeId, previous: G::NodeId) {
+ self.came_from.insert(node, previous);
+ }
+
+ fn reconstruct_path_to(&self, last: G::NodeId) -> Vec<G::NodeId> {
+ let mut path = vec![last];
+
+ let mut current = last;
+ while let Some(&previous) = self.came_from.get(&current) {
+ path.push(previous);
+ current = previous;
+ }
+
+ path.reverse();
+
+ path
+ }
+}
diff --git a/vendor/petgraph/src/csr.rs b/vendor/petgraph/src/csr.rs
new file mode 100644
index 000000000..50a9ce290
--- /dev/null
+++ b/vendor/petgraph/src/csr.rs
@@ -0,0 +1,985 @@
+//! Compressed Sparse Row (CSR) is a sparse adjacency matrix graph.
+
+use std::cmp::{max, Ordering};
+use std::iter::{Enumerate, Zip};
+use std::marker::PhantomData;
+use std::ops::{Index, IndexMut, Range};
+use std::slice::Windows;
+
+use crate::visit::{Data, GraphProp, IntoEdgeReferences, NodeCount};
+use crate::visit::{EdgeRef, GraphBase, IntoEdges, IntoNeighbors, NodeIndexable};
+use crate::visit::{IntoNodeIdentifiers, NodeCompactIndexable, Visitable};
+
+use crate::util::zip;
+
+#[doc(no_inline)]
+pub use crate::graph::{DefaultIx, IndexType};
+
+use crate::{Directed, EdgeType, IntoWeightedEdge};
+
+/// Csr node index type, a plain integer.
+pub type NodeIndex<Ix = DefaultIx> = Ix;
+/// Csr edge index type, a plain integer.
+pub type EdgeIndex = usize;
+
+const BINARY_SEARCH_CUTOFF: usize = 32;
+
+/// Compressed Sparse Row ([`CSR`]) is a sparse adjacency matrix graph.
+///
+/// `CSR` is parameterized over:
+///
+/// - Associated data `N` for nodes and `E` for edges, called *weights*.
+/// The associated data can be of arbitrary type.
+/// - Edge type `Ty` that determines whether the graph edges are directed or undirected.
+/// - Index type `Ix`, which determines the maximum size of the graph.
+///
+///
+/// Using **O(|E| + |V|)** space.
+///
+/// Self loops are allowed, no parallel edges.
+///
+/// Fast iteration of the outgoing edges of a vertex.
+///
+/// [`CSR`]: https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_(CSR,_CRS_or_Yale_format)
+#[derive(Debug)]
+pub struct Csr<N = (), E = (), Ty = Directed, Ix = DefaultIx> {
+ /// Column of next edge
+ column: Vec<NodeIndex<Ix>>,
+ /// weight of each edge; lock step with column
+ edges: Vec<E>,
+ /// Index of start of row Always node_count + 1 long.
+ /// Last element is always equal to column.len()
+ row: Vec<usize>,
+ node_weights: Vec<N>,
+ edge_count: usize,
+ ty: PhantomData<Ty>,
+}
+
+impl<N, E, Ty, Ix> Default for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<N: Clone, E: Clone, Ty, Ix: Clone> Clone for Csr<N, E, Ty, Ix> {
+ fn clone(&self) -> Self {
+ Csr {
+ column: self.column.clone(),
+ edges: self.edges.clone(),
+ row: self.row.clone(),
+ node_weights: self.node_weights.clone(),
+ edge_count: self.edge_count,
+ ty: self.ty,
+ }
+ }
+}
+
+impl<N, E, Ty, Ix> Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ /// Create an empty `Csr`.
+ pub fn new() -> Self {
+ Csr {
+ column: vec![],
+ edges: vec![],
+ row: vec![0; 1],
+ node_weights: vec![],
+ edge_count: 0,
+ ty: PhantomData,
+ }
+ }
+
+ /// Create a new [`Csr`] with `n` nodes. `N` must implement [`Default`] for the weight of each node.
+ ///
+ /// [`Default`]: https://doc.rust-lang.org/nightly/core/default/trait.Default.html
+ /// [`Csr`]: #struct.Csr.html
+ ///
+ /// # Example
+ /// ```rust
+ /// use petgraph::csr::Csr;
+ /// use petgraph::prelude::*;
+ ///
+ /// let graph = Csr::<u8,()>::with_nodes(5);
+ /// assert_eq!(graph.node_count(),5);
+ /// assert_eq!(graph.edge_count(),0);
+ ///
+ /// assert_eq!(graph[0],0);
+ /// assert_eq!(graph[4],0);
+ /// ```
+ pub fn with_nodes(n: usize) -> Self
+ where
+ N: Default,
+ {
+ Csr {
+ column: Vec::new(),
+ edges: Vec::new(),
+ row: vec![0; n + 1],
+ node_weights: (0..n).map(|_| N::default()).collect(),
+ edge_count: 0,
+ ty: PhantomData,
+ }
+ }
+}
+
+/// Csr creation error: edges were not in sorted order.
+#[derive(Clone, Debug)]
+pub struct EdgesNotSorted {
+ first_error: (usize, usize),
+}
+
+impl<N, E, Ix> Csr<N, E, Directed, Ix>
+where
+ Ix: IndexType,
+{
+ /// Create a new `Csr` from a sorted sequence of edges
+ ///
+ /// Edges **must** be sorted and unique, where the sort order is the default
+ /// order for the pair *(u, v)* in Rust (*u* has priority).
+ ///
+ /// Computes in **O(|E| + |V|)** time.
+ /// # Example
+ /// ```rust
+ /// use petgraph::csr::Csr;
+ /// use petgraph::prelude::*;
+ ///
+ /// let graph = Csr::<(),()>::from_sorted_edges(&[
+ /// (0, 1), (0, 2),
+ /// (1, 0), (1, 2), (1, 3),
+ /// (2, 0),
+ /// (3, 1),
+ /// ]);
+ /// ```
+ pub fn from_sorted_edges<Edge>(edges: &[Edge]) -> Result<Self, EdgesNotSorted>
+ where
+ Edge: Clone + IntoWeightedEdge<E, NodeId = NodeIndex<Ix>>,
+ N: Default,
+ {
+ let max_node_id = match edges
+ .iter()
+ .map(|edge| {
+ let (x, y, _) = edge.clone().into_weighted_edge();
+ max(x.index(), y.index())
+ })
+ .max()
+ {
+ None => return Ok(Self::with_nodes(0)),
+ Some(x) => x,
+ };
+ let mut self_ = Self::with_nodes(max_node_id + 1);
+ let mut iter = edges.iter().cloned().peekable();
+ {
+ let mut rows = self_.row.iter_mut();
+
+ let mut node = 0;
+ let mut rstart = 0;
+ let mut last_target;
+ 'outer: for r in &mut rows {
+ *r = rstart;
+ last_target = None;
+ 'inner: loop {
+ if let Some(edge) = iter.peek() {
+ let (n, m, weight) = edge.clone().into_weighted_edge();
+ // check that the edges are in increasing sequence
+ if node > n.index() {
+ return Err(EdgesNotSorted {
+ first_error: (n.index(), m.index()),
+ });
+ }
+ /*
+ debug_assert!(node <= n.index(),
+ concat!("edges are not sorted, ",
+ "failed assertion source {:?} <= {:?} ",
+ "for edge {:?}"),
+ node, n, (n, m));
+ */
+ if n.index() != node {
+ break 'inner;
+ }
+ // check that the edges are in increasing sequence
+ /*
+ debug_assert!(last_target.map_or(true, |x| m > x),
+ "edges are not sorted, failed assertion {:?} < {:?}",
+ last_target, m);
+ */
+ if !last_target.map_or(true, |x| m > x) {
+ return Err(EdgesNotSorted {
+ first_error: (n.index(), m.index()),
+ });
+ }
+ last_target = Some(m);
+ self_.column.push(m);
+ self_.edges.push(weight);
+ rstart += 1;
+ } else {
+ break 'outer;
+ }
+ iter.next();
+ }
+ node += 1;
+ }
+ for r in rows {
+ *r = rstart;
+ }
+ }
+
+ Ok(self_)
+ }
+}
+
+impl<N, E, Ty, Ix> Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ pub fn node_count(&self) -> usize {
+ self.row.len() - 1
+ }
+
+ pub fn edge_count(&self) -> usize {
+ if self.is_directed() {
+ self.column.len()
+ } else {
+ self.edge_count
+ }
+ }
+
+ pub fn is_directed(&self) -> bool {
+ Ty::is_directed()
+ }
+
+ /// Remove all edges
+ pub fn clear_edges(&mut self) {
+ self.column.clear();
+ self.edges.clear();
+ for r in &mut self.row {
+ *r = 0;
+ }
+ if !self.is_directed() {
+ self.edge_count = 0;
+ }
+ }
+
+ /// Adds a new node with the given weight, returning the corresponding node index.
+ pub fn add_node(&mut self, weight: N) -> NodeIndex<Ix> {
+ let i = self.row.len() - 1;
+ self.row.insert(i, self.column.len());
+ self.node_weights.insert(i, weight);
+ Ix::new(i)
+ }
+
+ /// Return `true` if the edge was added
+ ///
+ /// If you add all edges in row-major order, the time complexity
+ /// is **O(|V|·|E|)** for the whole operation.
+ ///
+ /// **Panics** if `a` or `b` are out of bounds.
+ pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> bool
+ where
+ E: Clone,
+ {
+ let ret = self.add_edge_(a, b, weight.clone());
+ if ret && !self.is_directed() {
+ self.edge_count += 1;
+ }
+ if ret && !self.is_directed() && a != b {
+ let _ret2 = self.add_edge_(b, a, weight);
+ debug_assert_eq!(ret, _ret2);
+ }
+ ret
+ }
+
+ // Return false if the edge already exists
+ fn add_edge_(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> bool {
+ assert!(a.index() < self.node_count() && b.index() < self.node_count());
+ // a x b is at (a, b) in the matrix
+
+ // find current range of edges from a
+ let pos = match self.find_edge_pos(a, b) {
+ Ok(_) => return false, /* already exists */
+ Err(i) => i,
+ };
+ self.column.insert(pos, b);
+ self.edges.insert(pos, weight);
+ // update row vector
+ for r in &mut self.row[a.index() + 1..] {
+ *r += 1;
+ }
+ true
+ }
+
+ fn find_edge_pos(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Result<usize, usize> {
+ let (index, neighbors) = self.neighbors_of(a);
+ if neighbors.len() < BINARY_SEARCH_CUTOFF {
+ for (i, elt) in neighbors.iter().enumerate() {
+ match elt.cmp(&b) {
+ Ordering::Equal => return Ok(i + index),
+ Ordering::Greater => return Err(i + index),
+ Ordering::Less => {}
+ }
+ }
+ Err(neighbors.len() + index)
+ } else {
+ match neighbors.binary_search(&b) {
+ Ok(i) => Ok(i + index),
+ Err(i) => Err(i + index),
+ }
+ }
+ }
+
+ /// Computes in **O(log |V|)** time.
+ ///
+ /// **Panics** if the node `a` does not exist.
+ pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
+ self.find_edge_pos(a, b).is_ok()
+ }
+
+ fn neighbors_range(&self, a: NodeIndex<Ix>) -> Range<usize> {
+ let index = self.row[a.index()];
+ let end = self
+ .row
+ .get(a.index() + 1)
+ .cloned()
+ .unwrap_or_else(|| self.column.len());
+ index..end
+ }
+
+ fn neighbors_of(&self, a: NodeIndex<Ix>) -> (usize, &[Ix]) {
+ let r = self.neighbors_range(a);
+ (r.start, &self.column[r])
+ }
+
+ /// Computes in **O(1)** time.
+ ///
+ /// **Panics** if the node `a` does not exist.
+ pub fn out_degree(&self, a: NodeIndex<Ix>) -> usize {
+ let r = self.neighbors_range(a);
+ r.end - r.start
+ }
+
+ /// Computes in **O(1)** time.
+ ///
+ /// **Panics** if the node `a` does not exist.
+ pub fn neighbors_slice(&self, a: NodeIndex<Ix>) -> &[NodeIndex<Ix>] {
+ self.neighbors_of(a).1
+ }
+
+ /// Computes in **O(1)** time.
+ ///
+ /// **Panics** if the node `a` does not exist.
+ pub fn edges_slice(&self, a: NodeIndex<Ix>) -> &[E] {
+ &self.edges[self.neighbors_range(a)]
+ }
+
+ /// Return an iterator of all edges of `a`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges connected to `a`.
+ ///
+ /// **Panics** if the node `a` does not exist.<br>
+ /// Iterator element type is `EdgeReference<E, Ty, Ix>`.
+ pub fn edges(&self, a: NodeIndex<Ix>) -> Edges<E, Ty, Ix> {
+ let r = self.neighbors_range(a);
+ Edges {
+ index: r.start,
+ source: a,
+ iter: zip(&self.column[r.clone()], &self.edges[r]),
+ ty: self.ty,
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct Edges<'a, E: 'a, Ty = Directed, Ix: 'a = DefaultIx> {
+ index: usize,
+ source: NodeIndex<Ix>,
+ iter: Zip<SliceIter<'a, NodeIndex<Ix>>, SliceIter<'a, E>>,
+ ty: PhantomData<Ty>,
+}
+
+#[derive(Debug)]
+pub struct EdgeReference<'a, E: 'a, Ty, Ix: 'a = DefaultIx> {
+ index: EdgeIndex,
+ source: NodeIndex<Ix>,
+ target: NodeIndex<Ix>,
+ weight: &'a E,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, E, Ty, Ix: Copy> Clone for EdgeReference<'a, E, Ty, Ix> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<'a, E, Ty, Ix: Copy> Copy for EdgeReference<'a, E, Ty, Ix> {}
+
+impl<'a, Ty, E, Ix> EdgeReference<'a, E, Ty, Ix>
+where
+ Ty: EdgeType,
+{
+ /// Access the edge’s weight.
+ ///
+ /// **NOTE** that this method offers a longer lifetime
+ /// than the trait (unfortunately they don't match yet).
+ pub fn weight(&self) -> &'a E {
+ self.weight
+ }
+}
+
+impl<'a, E, Ty, Ix> EdgeRef for EdgeReference<'a, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeId = NodeIndex<Ix>;
+ type EdgeId = EdgeIndex;
+ type Weight = E;
+
+ fn source(&self) -> Self::NodeId {
+ self.source
+ }
+ fn target(&self) -> Self::NodeId {
+ self.target
+ }
+ fn weight(&self) -> &E {
+ self.weight
+ }
+ fn id(&self) -> Self::EdgeId {
+ self.index
+ }
+}
+
+impl<'a, E, Ty, Ix> Iterator for Edges<'a, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Item = EdgeReference<'a, E, Ty, Ix>;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(move |(&j, w)| {
+ let index = self.index;
+ self.index += 1;
+ EdgeReference {
+ index,
+ source: self.source,
+ target: j,
+ weight: w,
+ ty: PhantomData,
+ }
+ })
+ }
+}
+
+impl<N, E, Ty, Ix> Data for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeWeight = N;
+ type EdgeWeight = E;
+}
+
+impl<'a, N, E, Ty, Ix> IntoEdgeReferences for &'a Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type EdgeRef = EdgeReference<'a, E, Ty, Ix>;
+ type EdgeReferences = EdgeReferences<'a, E, Ty, Ix>;
+ fn edge_references(self) -> Self::EdgeReferences {
+ EdgeReferences {
+ index: 0,
+ source_index: Ix::new(0),
+ edge_ranges: self.row.windows(2).enumerate(),
+ column: &self.column,
+ edges: &self.edges,
+ iter: zip(&[], &[]),
+ ty: self.ty,
+ }
+ }
+}
+
+pub struct EdgeReferences<'a, E: 'a, Ty, Ix: 'a> {
+ source_index: NodeIndex<Ix>,
+ index: usize,
+ edge_ranges: Enumerate<Windows<'a, usize>>,
+ column: &'a [NodeIndex<Ix>],
+ edges: &'a [E],
+ iter: Zip<SliceIter<'a, NodeIndex<Ix>>, SliceIter<'a, E>>,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, E, Ty, Ix> Iterator for EdgeReferences<'a, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Item = EdgeReference<'a, E, Ty, Ix>;
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ if let Some((&j, w)) = self.iter.next() {
+ let index = self.index;
+ self.index += 1;
+ return Some(EdgeReference {
+ index,
+ source: self.source_index,
+ target: j,
+ weight: w,
+ ty: PhantomData,
+ });
+ }
+ if let Some((i, w)) = self.edge_ranges.next() {
+ let a = w[0];
+ let b = w[1];
+ self.iter = zip(&self.column[a..b], &self.edges[a..b]);
+ self.source_index = Ix::new(i);
+ } else {
+ return None;
+ }
+ }
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoEdges for &'a Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Edges = Edges<'a, E, Ty, Ix>;
+ fn edges(self, a: Self::NodeId) -> Self::Edges {
+ self.edges(a)
+ }
+}
+
+impl<N, E, Ty, Ix> GraphBase for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeId = NodeIndex<Ix>;
+ type EdgeId = EdgeIndex; // index into edges vector
+}
+
+use fixedbitset::FixedBitSet;
+
+impl<N, E, Ty, Ix> Visitable for Csr<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());
+ }
+}
+
+use std::slice::Iter as SliceIter;
+
+#[derive(Clone, Debug)]
+pub struct Neighbors<'a, Ix: 'a = DefaultIx> {
+ iter: SliceIter<'a, NodeIndex<Ix>>,
+}
+
+impl<'a, Ix> Iterator for Neighbors<'a, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = NodeIndex<Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().cloned()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoNeighbors for &'a Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Neighbors = Neighbors<'a, Ix>;
+
+ /// Return an iterator of all neighbors of `a`.
+ ///
+ /// - `Directed`: Targets of outgoing edges from `a`.
+ /// - `Undirected`: Opposing endpoints of all edges connected to `a`.
+ ///
+ /// **Panics** if the node `a` does not exist.<br>
+ /// Iterator element type is `NodeIndex<Ix>`.
+ fn neighbors(self, a: Self::NodeId) -> Self::Neighbors {
+ Neighbors {
+ iter: self.neighbors_slice(a).iter(),
+ }
+ }
+}
+
+impl<N, E, Ty, Ix> NodeIndexable for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_bound(&self) -> usize {
+ self.node_count()
+ }
+ fn to_index(&self, a: Self::NodeId) -> usize {
+ a.index()
+ }
+ fn from_index(&self, ix: usize) -> Self::NodeId {
+ Ix::new(ix)
+ }
+}
+
+impl<N, E, Ty, Ix> NodeCompactIndexable for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+}
+
+impl<N, E, Ty, Ix> Index<NodeIndex<Ix>> for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Output = N;
+
+ fn index(&self, ix: NodeIndex<Ix>) -> &N {
+ &self.node_weights[ix.index()]
+ }
+}
+
+impl<N, E, Ty, Ix> IndexMut<NodeIndex<Ix>> for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn index_mut(&mut self, ix: NodeIndex<Ix>) -> &mut N {
+ &mut self.node_weights[ix.index()]
+ }
+}
+
+pub struct NodeIdentifiers<Ix = DefaultIx> {
+ r: Range<usize>,
+ ty: PhantomData<Ix>,
+}
+
+impl<Ix> Iterator for NodeIdentifiers<Ix>
+where
+ Ix: IndexType,
+{
+ type Item = NodeIndex<Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.r.next().map(Ix::new)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.r.size_hint()
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoNodeIdentifiers for &'a Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeIdentifiers = NodeIdentifiers<Ix>;
+ fn node_identifiers(self) -> Self::NodeIdentifiers {
+ NodeIdentifiers {
+ r: 0..self.node_count(),
+ ty: PhantomData,
+ }
+ }
+}
+
+impl<N, E, Ty, Ix> NodeCount for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_count(&self) -> usize {
+ (*self).node_count()
+ }
+}
+
+impl<N, E, Ty, Ix> GraphProp for Csr<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type EdgeType = Ty;
+}
+
+/*
+ *
+Example
+
+[ a 0 b
+ c d e
+ 0 0 f ]
+
+Values: [a, b, c, d, e, f]
+Column: [0, 2, 0, 1, 2, 2]
+Row : [0, 2, 5] <- value index of row start
+
+ * */
+
+#[cfg(test)]
+mod tests {
+ use super::Csr;
+ use crate::algo::bellman_ford;
+ use crate::algo::tarjan_scc;
+ use crate::visit::Dfs;
+ use crate::visit::VisitMap;
+ use crate::Undirected;
+
+ #[test]
+ fn csr1() {
+ let mut m: Csr = Csr::with_nodes(3);
+ m.add_edge(0, 0, ());
+ m.add_edge(1, 2, ());
+ m.add_edge(2, 2, ());
+ m.add_edge(0, 2, ());
+ m.add_edge(1, 0, ());
+ m.add_edge(1, 1, ());
+ println!("{:?}", m);
+ assert_eq!(&m.column, &[0, 2, 0, 1, 2, 2]);
+ assert_eq!(&m.row, &[0, 2, 5, 6]);
+
+ let added = m.add_edge(1, 2, ());
+ assert!(!added);
+ assert_eq!(&m.column, &[0, 2, 0, 1, 2, 2]);
+ assert_eq!(&m.row, &[0, 2, 5, 6]);
+
+ assert_eq!(m.neighbors_slice(1), &[0, 1, 2]);
+ assert_eq!(m.node_count(), 3);
+ assert_eq!(m.edge_count(), 6);
+ }
+
+ #[test]
+ fn csr_undirected() {
+ /*
+ [ 1 . 1
+ . . 1
+ 1 1 1 ]
+ */
+
+ let mut m: Csr<(), (), Undirected> = Csr::with_nodes(3);
+ m.add_edge(0, 0, ());
+ m.add_edge(0, 2, ());
+ m.add_edge(1, 2, ());
+ m.add_edge(2, 2, ());
+ println!("{:?}", m);
+ assert_eq!(&m.column, &[0, 2, 2, 0, 1, 2]);
+ assert_eq!(&m.row, &[0, 2, 3, 6]);
+ assert_eq!(m.node_count(), 3);
+ assert_eq!(m.edge_count(), 4);
+ }
+
+ #[should_panic]
+ #[test]
+ fn csr_from_error_1() {
+ // not sorted in source
+ let m: Csr = Csr::from_sorted_edges(&[(0, 1), (1, 0), (0, 2)]).unwrap();
+ println!("{:?}", m);
+ }
+
+ #[should_panic]
+ #[test]
+ fn csr_from_error_2() {
+ // not sorted in target
+ let m: Csr = Csr::from_sorted_edges(&[(0, 1), (1, 0), (1, 2), (1, 1)]).unwrap();
+ println!("{:?}", m);
+ }
+
+ #[test]
+ fn csr_from() {
+ let m: Csr =
+ Csr::from_sorted_edges(&[(0, 1), (0, 2), (1, 0), (1, 1), (2, 2), (2, 4)]).unwrap();
+ println!("{:?}", m);
+ assert_eq!(m.neighbors_slice(0), &[1, 2]);
+ assert_eq!(m.neighbors_slice(1), &[0, 1]);
+ assert_eq!(m.neighbors_slice(2), &[2, 4]);
+ assert_eq!(m.node_count(), 5);
+ assert_eq!(m.edge_count(), 6);
+ }
+
+ #[test]
+ fn csr_dfs() {
+ let mut m: Csr = Csr::from_sorted_edges(&[
+ (0, 1),
+ (0, 2),
+ (1, 0),
+ (1, 1),
+ (1, 3),
+ (2, 2),
+ // disconnected subgraph
+ (4, 4),
+ (4, 5),
+ ])
+ .unwrap();
+ println!("{:?}", m);
+ let mut dfs = Dfs::new(&m, 0);
+ while let Some(_) = dfs.next(&m) {}
+ for i in 0..m.node_count() - 2 {
+ assert!(dfs.discovered.is_visited(&i), "visited {}", i)
+ }
+ assert!(!dfs.discovered[4]);
+ assert!(!dfs.discovered[5]);
+
+ m.add_edge(1, 4, ());
+ println!("{:?}", m);
+
+ dfs.reset(&m);
+ dfs.move_to(0);
+ while let Some(_) = dfs.next(&m) {}
+
+ for i in 0..m.node_count() {
+ assert!(dfs.discovered[i], "visited {}", i)
+ }
+ }
+
+ #[test]
+ fn csr_tarjan() {
+ let m: Csr = Csr::from_sorted_edges(&[
+ (0, 1),
+ (0, 2),
+ (1, 0),
+ (1, 1),
+ (1, 3),
+ (2, 2),
+ (2, 4),
+ (4, 4),
+ (4, 5),
+ (5, 2),
+ ])
+ .unwrap();
+ println!("{:?}", m);
+ println!("{:?}", tarjan_scc(&m));
+ }
+
+ #[test]
+ fn test_bellman_ford() {
+ let m: Csr<(), _> = Csr::from_sorted_edges(&[
+ (0, 1, 0.5),
+ (0, 2, 2.),
+ (1, 0, 1.),
+ (1, 1, 1.),
+ (1, 2, 1.),
+ (1, 3, 1.),
+ (2, 3, 3.),
+ (4, 5, 1.),
+ (5, 7, 2.),
+ (6, 7, 1.),
+ (7, 8, 3.),
+ ])
+ .unwrap();
+ println!("{:?}", m);
+ let result = bellman_ford(&m, 0).unwrap();
+ println!("{:?}", result);
+ let answer = [0., 0.5, 1.5, 1.5];
+ assert_eq!(&answer, &result.0[..4]);
+ assert!(answer[4..].iter().all(|&x| f64::is_infinite(x)));
+ }
+
+ #[test]
+ fn test_bellman_ford_neg_cycle() {
+ let m: Csr<(), _> = Csr::from_sorted_edges(&[
+ (0, 1, 0.5),
+ (0, 2, 2.),
+ (1, 0, 1.),
+ (1, 1, -1.),
+ (1, 2, 1.),
+ (1, 3, 1.),
+ (2, 3, 3.),
+ ])
+ .unwrap();
+ let result = bellman_ford(&m, 0);
+ assert!(result.is_err());
+ }
+
+ #[test]
+ fn test_edge_references() {
+ use crate::visit::EdgeRef;
+ use crate::visit::IntoEdgeReferences;
+ let m: Csr<(), _> = Csr::from_sorted_edges(&[
+ (0, 1, 0.5),
+ (0, 2, 2.),
+ (1, 0, 1.),
+ (1, 1, 1.),
+ (1, 2, 1.),
+ (1, 3, 1.),
+ (2, 3, 3.),
+ (4, 5, 1.),
+ (5, 7, 2.),
+ (6, 7, 1.),
+ (7, 8, 3.),
+ ])
+ .unwrap();
+ let mut copy = Vec::new();
+ for e in m.edge_references() {
+ copy.push((e.source(), e.target(), *e.weight()));
+ println!("{:?}", e);
+ }
+ let m2: Csr<(), _> = Csr::from_sorted_edges(&copy).unwrap();
+ assert_eq!(&m.row, &m2.row);
+ assert_eq!(&m.column, &m2.column);
+ assert_eq!(&m.edges, &m2.edges);
+ }
+
+ #[test]
+ fn test_add_node() {
+ let mut g: Csr = Csr::new();
+ let a = g.add_node(());
+ let b = g.add_node(());
+ let c = g.add_node(());
+
+ assert!(g.add_edge(a, b, ()));
+ assert!(g.add_edge(b, c, ()));
+ assert!(g.add_edge(c, a, ()));
+
+ println!("{:?}", g);
+
+ assert_eq!(g.node_count(), 3);
+
+ assert_eq!(g.neighbors_slice(a), &[b]);
+ assert_eq!(g.neighbors_slice(b), &[c]);
+ assert_eq!(g.neighbors_slice(c), &[a]);
+
+ assert_eq!(g.edge_count(), 3);
+ }
+
+ #[test]
+ fn test_add_node_with_existing_edges() {
+ let mut g: Csr = Csr::new();
+ let a = g.add_node(());
+ let b = g.add_node(());
+
+ assert!(g.add_edge(a, b, ()));
+
+ let c = g.add_node(());
+
+ println!("{:?}", g);
+
+ assert_eq!(g.node_count(), 3);
+
+ assert_eq!(g.neighbors_slice(a), &[b]);
+ assert_eq!(g.neighbors_slice(b), &[]);
+ assert_eq!(g.neighbors_slice(c), &[]);
+
+ assert_eq!(g.edge_count(), 1);
+ }
+}
diff --git a/vendor/petgraph/src/data.rs b/vendor/petgraph/src/data.rs
new file mode 100644
index 000000000..7bb541140
--- /dev/null
+++ b/vendor/petgraph/src/data.rs
@@ -0,0 +1,474 @@
+//! Graph traits for associated data and graph construction.
+
+use crate::graph::IndexType;
+#[cfg(feature = "graphmap")]
+use crate::graphmap::{GraphMap, NodeTrait};
+#[cfg(feature = "stable_graph")]
+use crate::stable_graph::StableGraph;
+use crate::visit::{Data, NodeCount, NodeIndexable, Reversed};
+use crate::EdgeType;
+use crate::Graph;
+
+trait_template! {
+ /// Access node and edge weights (associated data).
+pub trait DataMap : Data {
+ @section self
+ fn node_weight(self: &Self, id: Self::NodeId) -> Option<&Self::NodeWeight>;
+ fn edge_weight(self: &Self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>;
+}
+}
+
+macro_rules! access0 {
+ ($e:expr) => {
+ $e.0
+ };
+}
+
+DataMap! {delegate_impl []}
+DataMap! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
+DataMap! {delegate_impl [[G], G, Reversed<G>, access0]}
+
+trait_template! {
+ /// Access node and edge weights mutably.
+pub trait DataMapMut : DataMap {
+ @section self
+ fn node_weight_mut(self: &mut Self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>;
+ fn edge_weight_mut(self: &mut Self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>;
+}
+}
+
+DataMapMut! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
+DataMapMut! {delegate_impl [[G], G, Reversed<G>, access0]}
+
+/// A graph that can be extended with further nodes and edges
+pub trait Build: Data + NodeCount {
+ fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId;
+ /// Add a new edge. If parallel edges (duplicate) are not allowed and
+ /// the edge already exists, return `None`.
+ fn add_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Option<Self::EdgeId> {
+ Some(self.update_edge(a, b, weight))
+ }
+ /// Add or update the edge from `a` to `b`. Return the id of the affected
+ /// edge.
+ fn update_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Self::EdgeId;
+}
+
+/// A graph that can be created
+pub trait Create: Build + Default {
+ fn with_capacity(nodes: usize, edges: usize) -> Self;
+}
+
+impl<N, E, Ty, Ix> Data for Graph<N, E, Ty, Ix>
+where
+ Ix: IndexType,
+{
+ type NodeWeight = N;
+ type EdgeWeight = E;
+}
+
+impl<N, E, Ty, Ix> DataMap for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
+ self.node_weight(id)
+ }
+ fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
+ self.edge_weight(id)
+ }
+}
+
+impl<N, E, Ty, Ix> DataMapMut for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
+ self.node_weight_mut(id)
+ }
+ fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
+ self.edge_weight_mut(id)
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> DataMap for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
+ self.node_weight(id)
+ }
+ fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
+ self.edge_weight(id)
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> DataMapMut for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
+ self.node_weight_mut(id)
+ }
+ fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
+ self.edge_weight_mut(id)
+ }
+}
+
+impl<N, E, Ty, Ix> Build for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
+ self.add_node(weight)
+ }
+ fn add_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Option<Self::EdgeId> {
+ Some(self.add_edge(a, b, weight))
+ }
+ fn update_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Self::EdgeId {
+ self.update_edge(a, b, weight)
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> Build for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
+ self.add_node(weight)
+ }
+ fn add_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Option<Self::EdgeId> {
+ Some(self.add_edge(a, b, weight))
+ }
+ fn update_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Self::EdgeId {
+ self.update_edge(a, b, weight)
+ }
+}
+
+#[cfg(feature = "graphmap")]
+impl<N, E, Ty> Build for GraphMap<N, E, Ty>
+where
+ Ty: EdgeType,
+ N: NodeTrait,
+{
+ fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
+ self.add_node(weight)
+ }
+ fn add_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Option<Self::EdgeId> {
+ if self.contains_edge(a, b) {
+ None
+ } else {
+ let r = self.add_edge(a, b, weight);
+ debug_assert!(r.is_none());
+ Some((a, b))
+ }
+ }
+ fn update_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Self::EdgeId {
+ self.add_edge(a, b, weight);
+ (a, b)
+ }
+}
+
+impl<N, E, Ty, Ix> Create for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn with_capacity(nodes: usize, edges: usize) -> Self {
+ Self::with_capacity(nodes, edges)
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> Create for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn with_capacity(nodes: usize, edges: usize) -> Self {
+ Self::with_capacity(nodes, edges)
+ }
+}
+
+#[cfg(feature = "graphmap")]
+impl<N, E, Ty> Create for GraphMap<N, E, Ty>
+where
+ Ty: EdgeType,
+ N: NodeTrait,
+{
+ fn with_capacity(nodes: usize, edges: usize) -> Self {
+ Self::with_capacity(nodes, edges)
+ }
+}
+
+/// A graph element.
+///
+/// A sequence of Elements, for example an iterator, is laid out as follows:
+/// Nodes are implicitly given the index of their appearance in the sequence.
+/// The edges’ source and target fields refer to these indices.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum Element<N, E> {
+ /// A graph node.
+ Node { weight: N },
+ /// A graph edge.
+ Edge {
+ source: usize,
+ target: usize,
+ weight: E,
+ },
+}
+
+/// Create a graph from an iterator of elements.
+pub trait FromElements: Create {
+ fn from_elements<I>(iterable: I) -> Self
+ where
+ Self: Sized,
+ I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
+ {
+ let mut gr = Self::with_capacity(0, 0);
+ // usize -> NodeId map
+ let mut map = Vec::new();
+ for element in iterable {
+ match element {
+ Element::Node { weight } => {
+ map.push(gr.add_node(weight));
+ }
+ Element::Edge {
+ source,
+ target,
+ weight,
+ } => {
+ gr.add_edge(map[source], map[target], weight);
+ }
+ }
+ }
+ gr
+ }
+}
+
+fn from_elements_indexable<G, I>(iterable: I) -> G
+where
+ G: Create + NodeIndexable,
+ I: IntoIterator<Item = Element<G::NodeWeight, G::EdgeWeight>>,
+{
+ let mut gr = G::with_capacity(0, 0);
+ let map = |gr: &G, i| gr.from_index(i);
+ for element in iterable {
+ match element {
+ Element::Node { weight } => {
+ gr.add_node(weight);
+ }
+ Element::Edge {
+ source,
+ target,
+ weight,
+ } => {
+ let from = map(&gr, source);
+ let to = map(&gr, target);
+ gr.add_edge(from, to, weight);
+ }
+ }
+ }
+ gr
+}
+
+impl<N, E, Ty, Ix> FromElements for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn from_elements<I>(iterable: I) -> Self
+ where
+ Self: Sized,
+ I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
+ {
+ from_elements_indexable(iterable)
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+impl<N, E, Ty, Ix> FromElements for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn from_elements<I>(iterable: I) -> Self
+ where
+ Self: Sized,
+ I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
+ {
+ from_elements_indexable(iterable)
+ }
+}
+
+#[cfg(feature = "graphmap")]
+impl<N, E, Ty> FromElements for GraphMap<N, E, Ty>
+where
+ Ty: EdgeType,
+ N: NodeTrait,
+{
+ fn from_elements<I>(iterable: I) -> Self
+ where
+ Self: Sized,
+ I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
+ {
+ from_elements_indexable(iterable)
+ }
+}
+
+/// Iterator adaptors for iterators of `Element`.
+pub trait ElementIterator<N, E>: Iterator<Item = Element<N, E>> {
+ /// Create an iterator adaptor that filters graph elements.
+ ///
+ /// The function `f` is called with each element and if its return value
+ /// is `true` the element is accepted and if `false` it is removed.
+ /// `f` is called with mutable references to the node and edge weights,
+ /// so that they can be mutated (but the edge endpoints can not).
+ ///
+ /// This filter adapts the edge source and target indices in the
+ /// stream so that they are correct after the removals.
+ fn filter_elements<F>(self, f: F) -> FilterElements<Self, F>
+ where
+ Self: Sized,
+ F: FnMut(Element<&mut N, &mut E>) -> bool,
+ {
+ FilterElements {
+ iter: self,
+ node_index: 0,
+ map: Vec::new(),
+ f,
+ }
+ }
+}
+
+impl<N, E, I: ?Sized> ElementIterator<N, E> for I where I: Iterator<Item = Element<N, E>> {}
+
+/// An iterator that filters graph elements.
+///
+/// See [`.filter_elements()`][1] for more information.
+///
+/// [1]: trait.ElementIterator.html#method.filter_elements
+pub struct FilterElements<I, F> {
+ iter: I,
+ node_index: usize,
+ map: Vec<usize>,
+ f: F,
+}
+
+impl<I, F, N, E> Iterator for FilterElements<I, F>
+where
+ I: Iterator<Item = Element<N, E>>,
+ F: FnMut(Element<&mut N, &mut E>) -> bool,
+{
+ type Item = Element<N, E>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ let mut elt = match self.iter.next() {
+ None => return None,
+ Some(elt) => elt,
+ };
+ let keep = (self.f)(match elt {
+ Element::Node { ref mut weight } => Element::Node { weight },
+ Element::Edge {
+ source,
+ target,
+ ref mut weight,
+ } => Element::Edge {
+ source,
+ target,
+ weight,
+ },
+ });
+ let is_node = if let Element::Node { .. } = elt {
+ true
+ } else {
+ false
+ };
+ if !keep && is_node {
+ self.map.push(self.node_index);
+ }
+ if is_node {
+ self.node_index += 1;
+ }
+ if !keep {
+ continue;
+ }
+
+ // map edge parts
+ match elt {
+ Element::Edge {
+ ref mut source,
+ ref mut target,
+ ..
+ } => {
+ // Find the node indices in the map of removed ones.
+ // If a node was removed, the edge is as well.
+ // Otherwise the counts are adjusted by the number of nodes
+ // removed.
+ // Example: map: [1, 3, 4, 6]
+ // binary search for 2, result is Err(1). One node has been
+ // removed before 2.
+ match self.map.binary_search(source) {
+ Ok(_) => continue,
+ Err(i) => *source -= i,
+ }
+ match self.map.binary_search(target) {
+ Ok(_) => continue,
+ Err(i) => *target -= i,
+ }
+ }
+ Element::Node { .. } => {}
+ }
+ return Some(elt);
+ }
+ }
+}
diff --git a/vendor/petgraph/src/dijkstra.rs b/vendor/petgraph/src/dijkstra.rs
new file mode 100644
index 000000000..3d1fda606
--- /dev/null
+++ b/vendor/petgraph/src/dijkstra.rs
@@ -0,0 +1,122 @@
+use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::collections::{BinaryHeap, HashMap};
+
+use std::hash::Hash;
+
+use super::visit::{EdgeRef, IntoEdges, VisitMap, Visitable};
+use crate::algo::Measure;
+use crate::scored::MinScored;
+
+/// \[Generic\] Dijkstra's shortest path algorithm.
+///
+/// Compute the length of the shortest path from `start` to every reachable
+/// node.
+///
+/// The graph should be `Visitable` and implement `IntoEdges`. The function
+/// `edge_cost` should return the cost for a particular edge, which is used
+/// to compute path costs. Edge costs must be non-negative.
+///
+/// If `goal` is not `None`, then the algorithm terminates once the `goal` node's
+/// cost is calculated.
+///
+/// Returns a `HashMap` that maps `NodeId` to path cost.
+/// # Example
+/// ```rust
+/// use petgraph::Graph;
+/// use petgraph::algo::dijkstra;
+/// use petgraph::prelude::*;
+/// use std::collections::HashMap;
+///
+/// let mut graph : Graph<(),(),Directed>= Graph::new();
+/// let a = graph.add_node(()); // node with no weight
+/// let b = graph.add_node(());
+/// let c = graph.add_node(());
+/// let d = graph.add_node(());
+/// let e = graph.add_node(());
+/// let f = graph.add_node(());
+/// let g = graph.add_node(());
+/// let h = graph.add_node(());
+/// // z will be in another connected component
+/// let z = graph.add_node(());
+///
+/// graph.extend_with_edges(&[
+/// (a, b),
+/// (b, c),
+/// (c, d),
+/// (d, a),
+/// (e, f),
+/// (b, e),
+/// (f, g),
+/// (g, h),
+/// (h, e)
+/// ]);
+/// // a ----> b ----> e ----> f
+/// // ^ | ^ |
+/// // | v | v
+/// // d <---- c h <---- g
+///
+/// let expected_res: HashMap<NodeIndex, usize> = [
+/// (a, 3),
+/// (b, 0),
+/// (c, 1),
+/// (d, 2),
+/// (e, 1),
+/// (f, 2),
+/// (g, 3),
+/// (h, 4)
+/// ].iter().cloned().collect();
+/// let res = dijkstra(&graph,b,None, |_| 1);
+/// assert_eq!(res, expected_res);
+/// // z is not inside res because there is not path from b to z.
+/// ```
+pub fn dijkstra<G, F, K>(
+ graph: G,
+ start: G::NodeId,
+ goal: Option<G::NodeId>,
+ mut edge_cost: F,
+) -> HashMap<G::NodeId, K>
+where
+ G: IntoEdges + Visitable,
+ G::NodeId: Eq + Hash,
+ F: FnMut(G::EdgeRef) -> K,
+ K: Measure + Copy,
+{
+ let mut visited = graph.visit_map();
+ let mut scores = HashMap::new();
+ //let mut predecessor = HashMap::new();
+ let mut visit_next = BinaryHeap::new();
+ let zero_score = K::default();
+ scores.insert(start, zero_score);
+ visit_next.push(MinScored(zero_score, start));
+ while let Some(MinScored(node_score, node)) = visit_next.pop() {
+ if visited.is_visited(&node) {
+ continue;
+ }
+ if goal.as_ref() == Some(&node) {
+ break;
+ }
+ for edge in graph.edges(node) {
+ let next = edge.target();
+ if visited.is_visited(&next) {
+ continue;
+ }
+ let next_score = node_score + edge_cost(edge);
+ match scores.entry(next) {
+ Occupied(ent) => {
+ if next_score < *ent.get() {
+ *ent.into_mut() = next_score;
+ visit_next.push(MinScored(next_score, next));
+ //predecessor.insert(next.clone(), node.clone());
+ }
+ }
+ Vacant(ent) => {
+ ent.insert(next_score);
+ visit_next.push(MinScored(next_score, next));
+ //predecessor.insert(next.clone(), node.clone());
+ }
+ }
+ }
+ visited.visit(node);
+ }
+ scores
+}
diff --git a/vendor/petgraph/src/dot.rs b/vendor/petgraph/src/dot.rs
new file mode 100644
index 000000000..fa31fdfe8
--- /dev/null
+++ b/vendor/petgraph/src/dot.rs
@@ -0,0 +1,330 @@
+//! Simple graphviz dot file format output.
+
+use std::fmt::{self, Display, Write};
+
+use crate::visit::{
+ Data, EdgeRef, GraphBase, GraphProp, GraphRef, IntoEdgeReferences, IntoNodeReferences,
+ NodeIndexable, NodeRef,
+};
+
+/// `Dot` implements output to graphviz .dot format for a graph.
+///
+/// Formatting and options are rather simple, this is mostly intended
+/// for debugging. Exact output may change.
+///
+/// # Examples
+///
+/// ```
+/// use petgraph::Graph;
+/// use petgraph::dot::{Dot, Config};
+///
+/// let mut graph = Graph::<_, ()>::new();
+/// graph.add_node("A");
+/// graph.add_node("B");
+/// graph.add_node("C");
+/// graph.add_node("D");
+/// graph.extend_with_edges(&[
+/// (0, 1), (0, 2), (0, 3),
+/// (1, 2), (1, 3),
+/// (2, 3),
+/// ]);
+///
+/// println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
+///
+/// // In this case the output looks like this:
+/// //
+/// // digraph {
+/// // 0 [label="\"A\""]
+/// // 1 [label="\"B\""]
+/// // 2 [label="\"C\""]
+/// // 3 [label="\"D\""]
+/// // 0 -> 1
+/// // 0 -> 2
+/// // 0 -> 3
+/// // 1 -> 2
+/// // 1 -> 3
+/// // 2 -> 3
+/// // }
+///
+/// // If you need multiple config options, just list them all in the slice.
+/// ```
+pub struct Dot<'a, G>
+where
+ G: IntoEdgeReferences + IntoNodeReferences,
+{
+ graph: G,
+ config: &'a [Config],
+ get_edge_attributes: &'a dyn Fn(G, G::EdgeRef) -> String,
+ get_node_attributes: &'a dyn Fn(G, G::NodeRef) -> String,
+}
+
+static TYPE: [&str; 2] = ["graph", "digraph"];
+static EDGE: [&str; 2] = ["--", "->"];
+static INDENT: &str = " ";
+
+impl<'a, G> Dot<'a, G>
+where
+ G: GraphRef + IntoEdgeReferences + IntoNodeReferences,
+{
+ /// Create a `Dot` formatting wrapper with default configuration.
+ pub fn new(graph: G) -> Self {
+ Self::with_config(graph, &[])
+ }
+
+ /// Create a `Dot` formatting wrapper with custom configuration.
+ pub fn with_config(graph: G, config: &'a [Config]) -> Self {
+ Self::with_attr_getters(graph, config, &|_, _| "".to_string(), &|_, _| {
+ "".to_string()
+ })
+ }
+
+ pub fn with_attr_getters(
+ graph: G,
+ config: &'a [Config],
+ get_edge_attributes: &'a dyn Fn(G, G::EdgeRef) -> String,
+ get_node_attributes: &'a dyn Fn(G, G::NodeRef) -> String,
+ ) -> Self {
+ Dot {
+ graph,
+ config,
+ get_edge_attributes,
+ get_node_attributes,
+ }
+ }
+}
+
+/// `Dot` configuration.
+///
+/// This enum does not have an exhaustive definition (will be expanded)
+#[derive(Debug, PartialEq, Eq)]
+pub enum Config {
+ /// Use indices for node labels.
+ NodeIndexLabel,
+ /// Use indices for edge labels.
+ EdgeIndexLabel,
+ /// Use no edge labels.
+ EdgeNoLabel,
+ /// Use no node labels.
+ NodeNoLabel,
+ /// Do not print the graph/digraph string.
+ GraphContentOnly,
+ #[doc(hidden)]
+ _Incomplete(()),
+}
+
+impl<'a, G> Dot<'a, G>
+where
+ G: GraphBase + IntoNodeReferences + IntoEdgeReferences,
+{
+ fn graph_fmt<NF, EF, NW, EW>(
+ &self,
+ g: G,
+ f: &mut fmt::Formatter,
+ mut node_fmt: NF,
+ mut edge_fmt: EF,
+ ) -> fmt::Result
+ where
+ G: NodeIndexable + IntoNodeReferences + IntoEdgeReferences,
+ G: GraphProp + GraphBase,
+ G: Data<NodeWeight = NW, EdgeWeight = EW>,
+ NF: FnMut(&NW, &mut dyn FnMut(&dyn Display) -> fmt::Result) -> fmt::Result,
+ EF: FnMut(&EW, &mut dyn FnMut(&dyn Display) -> fmt::Result) -> fmt::Result,
+ {
+ if !self.config.contains(&Config::GraphContentOnly) {
+ writeln!(f, "{} {{", TYPE[g.is_directed() as usize])?;
+ }
+
+ // output all labels
+ for node in g.node_references() {
+ write!(f, "{}{} [ ", INDENT, g.to_index(node.id()),)?;
+ if !self.config.contains(&Config::NodeNoLabel) {
+ write!(f, "label = \"")?;
+ if self.config.contains(&Config::NodeIndexLabel) {
+ write!(f, "{}", g.to_index(node.id()))?;
+ } else {
+ node_fmt(node.weight(), &mut |d| Escaped(d).fmt(f))?;
+ }
+ write!(f, "\" ")?;
+ }
+ writeln!(f, "{}]", (self.get_node_attributes)(g, node))?;
+ }
+ // output all edges
+ for (i, edge) in g.edge_references().enumerate() {
+ write!(
+ f,
+ "{}{} {} {} [ ",
+ INDENT,
+ g.to_index(edge.source()),
+ EDGE[g.is_directed() as usize],
+ g.to_index(edge.target()),
+ )?;
+ if !self.config.contains(&Config::EdgeNoLabel) {
+ write!(f, "label = \"")?;
+ if self.config.contains(&Config::EdgeIndexLabel) {
+ write!(f, "{}", i)?;
+ } else {
+ edge_fmt(edge.weight(), &mut |d| Escaped(d).fmt(f))?;
+ }
+ write!(f, "\" ")?;
+ }
+ writeln!(f, "{}]", (self.get_edge_attributes)(g, edge))?;
+ }
+
+ if !self.config.contains(&Config::GraphContentOnly) {
+ writeln!(f, "}}")?;
+ }
+ Ok(())
+ }
+}
+
+impl<'a, G> fmt::Display for Dot<'a, G>
+where
+ G: IntoEdgeReferences + IntoNodeReferences + NodeIndexable + GraphProp,
+ G::EdgeWeight: fmt::Display,
+ G::NodeWeight: fmt::Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.graph_fmt(self.graph, f, |n, cb| cb(n), |e, cb| cb(e))
+ }
+}
+
+impl<'a, G> fmt::Debug for Dot<'a, G>
+where
+ G: IntoEdgeReferences + IntoNodeReferences + NodeIndexable + GraphProp,
+ G::EdgeWeight: fmt::Debug,
+ G::NodeWeight: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.graph_fmt(
+ self.graph,
+ f,
+ |n, cb| cb(&DebugFmt(n)),
+ |e, cb| cb(&DebugFmt(e)),
+ )
+ }
+}
+
+/// Escape for Graphviz
+struct Escaper<W>(W);
+
+impl<W> fmt::Write for Escaper<W>
+where
+ W: fmt::Write,
+{
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ for c in s.chars() {
+ self.write_char(c)?;
+ }
+ Ok(())
+ }
+
+ fn write_char(&mut self, c: char) -> fmt::Result {
+ match c {
+ '"' | '\\' => self.0.write_char('\\')?,
+ // \l is for left justified linebreak
+ '\n' => return self.0.write_str("\\l"),
+ _ => {}
+ }
+ self.0.write_char(c)
+ }
+}
+
+/// Pass Display formatting through a simple escaping filter
+struct Escaped<T>(T);
+
+impl<T> fmt::Display for Escaped<T>
+where
+ T: fmt::Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if f.alternate() {
+ writeln!(&mut Escaper(f), "{:#}", &self.0)
+ } else {
+ write!(&mut Escaper(f), "{}", &self.0)
+ }
+ }
+}
+
+/// Pass Debug formatting to Display
+struct DebugFmt<T>(T);
+
+impl<T> fmt::Display for DebugFmt<T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::{Config, Dot, Escaper};
+ use crate::prelude::Graph;
+ use crate::visit::NodeRef;
+ use std::fmt::Write;
+
+ #[test]
+ fn test_escape() {
+ let mut buff = String::new();
+ {
+ let mut e = Escaper(&mut buff);
+ let _ = e.write_str("\" \\ \n");
+ }
+ assert_eq!(buff, "\\\" \\\\ \\l");
+ }
+
+ fn simple_graph() -> Graph<&'static str, &'static str> {
+ let mut graph = Graph::<&str, &str>::new();
+ let a = graph.add_node("A");
+ let b = graph.add_node("B");
+ graph.add_edge(a, b, "edge_label");
+ graph
+ }
+
+ #[test]
+ fn test_nodeindexlable_option() {
+ let graph = simple_graph();
+ let dot = format!("{:?}", Dot::with_config(&graph, &[Config::NodeIndexLabel]));
+ assert_eq!(dot, "digraph {\n 0 [ label = \"0\" ]\n 1 [ label = \"1\" ]\n 0 -> 1 [ label = \"\\\"edge_label\\\"\" ]\n}\n");
+ }
+
+ #[test]
+ fn test_edgeindexlable_option() {
+ let graph = simple_graph();
+ let dot = format!("{:?}", Dot::with_config(&graph, &[Config::EdgeIndexLabel]));
+ assert_eq!(dot, "digraph {\n 0 [ label = \"\\\"A\\\"\" ]\n 1 [ label = \"\\\"B\\\"\" ]\n 0 -> 1 [ label = \"0\" ]\n}\n");
+ }
+
+ #[test]
+ fn test_edgenolable_option() {
+ let graph = simple_graph();
+ let dot = format!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
+ assert_eq!(dot, "digraph {\n 0 [ label = \"\\\"A\\\"\" ]\n 1 [ label = \"\\\"B\\\"\" ]\n 0 -> 1 [ ]\n}\n");
+ }
+
+ #[test]
+ fn test_nodenolable_option() {
+ let graph = simple_graph();
+ let dot = format!("{:?}", Dot::with_config(&graph, &[Config::NodeNoLabel]));
+ assert_eq!(
+ dot,
+ "digraph {\n 0 [ ]\n 1 [ ]\n 0 -> 1 [ label = \"\\\"edge_label\\\"\" ]\n}\n"
+ );
+ }
+
+ #[test]
+ fn test_with_attr_getters() {
+ let graph = simple_graph();
+ let dot = format!(
+ "{:?}",
+ Dot::with_attr_getters(
+ &graph,
+ &[Config::NodeNoLabel, Config::EdgeNoLabel],
+ &|_, er| format!("label = \"{}\"", er.weight().to_uppercase()),
+ &|_, nr| format!("label = \"{}\"", nr.weight().to_lowercase()),
+ ),
+ );
+ assert_eq!(dot, "digraph {\n 0 [ label = \"a\"]\n 1 [ label = \"b\"]\n 0 -> 1 [ label = \"EDGE_LABEL\"]\n}\n");
+ }
+}
diff --git a/vendor/petgraph/src/generate.rs b/vendor/petgraph/src/generate.rs
new file mode 100644
index 000000000..9dc7dbf4d
--- /dev/null
+++ b/vendor/petgraph/src/generate.rs
@@ -0,0 +1,133 @@
+//! ***Unstable.*** Graph generation.
+//!
+//! ***Unstable: API may change at any time.*** Depends on `feature = "generate"`.
+//!
+
+use crate::graph::NodeIndex;
+use crate::{Directed, EdgeType, Graph};
+
+// A DAG has the property that the adjacency matrix is lower triangular,
+// diagonal zero.
+//
+// This means we only allow edges i → j where i < j.
+//
+// The set of all DAG of a particular size is simply the power set of all
+// possible edges.
+//
+// For a graph of n=3 nodes we have (n - 1) * n / 2 = 3 possible edges.
+
+/// A graph generator of “all” graphs of a particular size.
+///
+/// ***Unstable: API may change at any time.*** Depends on `feature = "generate"`.
+pub struct Generator<Ty> {
+ acyclic: bool,
+ selfloops: bool,
+ nodes: usize,
+ /// number of possible edges
+ nedges: usize,
+ /// current edge bitmap
+ bits: u64,
+ g: Graph<(), (), Ty>,
+}
+
+impl Generator<Directed> {
+ /// Generate all possible Directed acyclic graphs (DAGs) of a particular number of vertices.
+ ///
+ /// These are only generated with one per isomorphism, so they use
+ /// one canonical node labeling where node *i* can only have edges to node *j* if *i < j*.
+ ///
+ /// For a graph of *k* vertices there are *e = (k - 1) k / 2* possible edges and
+ /// *2<sup>e</sup>* DAGs.
+ pub fn directed_acyclic(nodes: usize) -> Self {
+ assert!(nodes != 0);
+ let nedges = (nodes - 1) * nodes / 2;
+ assert!(nedges < 64);
+ Generator {
+ acyclic: true,
+ selfloops: false,
+ nodes: nodes,
+ nedges: nedges,
+ bits: !0,
+ g: Graph::with_capacity(nodes, nedges),
+ }
+ }
+}
+
+impl<Ty: EdgeType> Generator<Ty> {
+ /// Generate all possible graphs of a particular number of vertices.
+ ///
+ /// All permutations are generated, so the graphs are not unique down to isomorphism.
+ ///
+ /// For a graph of *k* vertices there are *e = k²* possible edges and
+ /// *2<sup>k<sup>2</sup></sup>* graphs.
+ pub fn all(nodes: usize, allow_selfloops: bool) -> Self {
+ let scale = if Ty::is_directed() { 1 } else { 2 };
+ let nedges = if allow_selfloops {
+ (nodes * nodes - nodes) / scale + nodes
+ } else {
+ (nodes * nodes) / scale - nodes
+ };
+ assert!(nedges < 64);
+ Generator {
+ acyclic: false,
+ selfloops: allow_selfloops,
+ nodes: nodes,
+ nedges: nedges,
+ bits: !0,
+ g: Graph::with_capacity(nodes, nedges),
+ }
+ }
+
+ fn state_to_graph(&mut self) -> &Graph<(), (), Ty> {
+ self.g.clear();
+ for _ in 0..self.nodes {
+ self.g.add_node(());
+ }
+ // For a DAG:
+ // interpret the bits in order, it's a lower triangular matrix:
+ // a b c d
+ // a x x x x
+ // b 0 x x x
+ // c 1 2 x x
+ // d 3 4 5 x
+ let mut bit = 0;
+ for i in 0..self.nodes {
+ let start = if self.acyclic || !self.g.is_directed() {
+ i
+ } else {
+ 0
+ };
+ for j in start..self.nodes {
+ if i == j && !self.selfloops {
+ continue;
+ }
+ if self.bits & (1u64 << bit) != 0 {
+ self.g.add_edge(NodeIndex::new(i), NodeIndex::new(j), ());
+ }
+
+ bit += 1;
+ }
+ }
+ &self.g
+ }
+
+ pub fn next_ref(&mut self) -> Option<&Graph<(), (), Ty>> {
+ if self.bits == !0 {
+ self.bits = 0;
+ } else {
+ self.bits += 1;
+ if self.bits >= 1u64 << self.nedges {
+ return None;
+ }
+ }
+ Some(self.state_to_graph())
+ }
+}
+
+impl<Ty: EdgeType> Iterator for Generator<Ty> {
+ type Item = Graph<(), (), Ty>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.next_ref().cloned()
+ }
+}
diff --git a/vendor/petgraph/src/graph_impl/frozen.rs b/vendor/petgraph/src/graph_impl/frozen.rs
new file mode 100644
index 000000000..1ba06d9d9
--- /dev/null
+++ b/vendor/petgraph/src/graph_impl/frozen.rs
@@ -0,0 +1,96 @@
+use std::ops::{Deref, Index, IndexMut};
+
+use super::Frozen;
+use crate::data::{DataMap, DataMapMut};
+use crate::graph::Graph;
+use crate::graph::{GraphIndex, IndexType};
+use crate::visit::{Data, GraphProp, IntoNeighborsDirected, IntoNodeIdentifiers, NodeIndexable};
+use crate::visit::{
+ GetAdjacencyMatrix, IntoEdges, IntoEdgesDirected, NodeCompactIndexable, NodeCount,
+};
+use crate::visit::{IntoEdgeReferences, IntoNeighbors, IntoNodeReferences, Visitable};
+use crate::{Direction, EdgeType};
+
+impl<'a, G> Frozen<'a, G> {
+ /// Create a new `Frozen` from a mutable reference to a graph.
+ pub fn new(gr: &'a mut G) -> Self {
+ Frozen(gr)
+ }
+}
+
+/// Deref allows transparent access to all shared reference (read-only)
+/// functionality in the underlying graph.
+impl<'a, G> Deref for Frozen<'a, G> {
+ type Target = G;
+ fn deref(&self) -> &G {
+ self.0
+ }
+}
+
+impl<'a, G, I> Index<I> for Frozen<'a, G>
+where
+ G: Index<I>,
+{
+ type Output = G::Output;
+ fn index(&self, i: I) -> &G::Output {
+ self.0.index(i)
+ }
+}
+
+impl<'a, G, I> IndexMut<I> for Frozen<'a, G>
+where
+ G: IndexMut<I>,
+{
+ fn index_mut(&mut self, i: I) -> &mut G::Output {
+ self.0.index_mut(i)
+ }
+}
+
+impl<'a, N, E, Ty, Ix> Frozen<'a, Graph<N, E, Ty, Ix>>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ /// Index the `Graph` by two indices, any combination of
+ /// node or edge indices is fine.
+ ///
+ /// **Panics** if the indices are equal or if they are out of bounds.
+ pub fn index_twice_mut<T, U>(
+ &mut self,
+ i: T,
+ j: U,
+ ) -> (
+ &mut <Graph<N, E, Ty, Ix> as Index<T>>::Output,
+ &mut <Graph<N, E, Ty, Ix> as Index<U>>::Output,
+ )
+ where
+ Graph<N, E, Ty, Ix>: IndexMut<T> + IndexMut<U>,
+ T: GraphIndex,
+ U: GraphIndex,
+ {
+ self.0.index_twice_mut(i, j)
+ }
+}
+
+macro_rules! access0 {
+ ($e:expr) => {
+ $e.0
+ };
+}
+
+Data! {delegate_impl [['a, G], G, Frozen<'a, G>, deref_twice]}
+DataMap! {delegate_impl [['a, G], G, Frozen<'a, G>, deref_twice]}
+DataMapMut! {delegate_impl [['a, G], G, Frozen<'a, G>, access0]}
+GetAdjacencyMatrix! {delegate_impl [['a, G], G, Frozen<'a, G>, deref_twice]}
+IntoEdgeReferences! {delegate_impl [['a, 'b, G], G, &'b Frozen<'a, G>, deref_twice]}
+IntoEdges! {delegate_impl [['a, 'b, G], G, &'b Frozen<'a, G>, deref_twice]}
+IntoEdgesDirected! {delegate_impl [['a, 'b, G], G, &'b Frozen<'a, G>, deref_twice]}
+IntoNeighbors! {delegate_impl [['a, 'b, G], G, &'b Frozen<'a, G>, deref_twice]}
+IntoNeighborsDirected! {delegate_impl [['a, 'b, G], G, &'b Frozen<'a, G>, deref_twice]}
+IntoNodeIdentifiers! {delegate_impl [['a, 'b, G], G, &'b Frozen<'a, G>, deref_twice]}
+IntoNodeReferences! {delegate_impl [['a, 'b, G], G, &'b Frozen<'a, G>, deref_twice]}
+NodeCompactIndexable! {delegate_impl [['a, G], G, Frozen<'a, G>, deref_twice]}
+NodeCount! {delegate_impl [['a, G], G, Frozen<'a, G>, deref_twice]}
+NodeIndexable! {delegate_impl [['a, G], G, Frozen<'a, G>, deref_twice]}
+GraphProp! {delegate_impl [['a, G], G, Frozen<'a, G>, deref_twice]}
+Visitable! {delegate_impl [['a, G], G, Frozen<'a, G>, deref_twice]}
diff --git a/vendor/petgraph/src/graph_impl/mod.rs b/vendor/petgraph/src/graph_impl/mod.rs
new file mode 100644
index 000000000..9fb43b3c4
--- /dev/null
+++ b/vendor/petgraph/src/graph_impl/mod.rs
@@ -0,0 +1,2172 @@
+use std::cmp;
+use std::fmt;
+use std::hash::Hash;
+use std::iter;
+use std::marker::PhantomData;
+use std::mem::size_of;
+use std::ops::{Index, IndexMut, Range};
+use std::slice;
+
+use crate::{Directed, Direction, EdgeType, Incoming, IntoWeightedEdge, Outgoing, Undirected};
+
+use crate::iter_format::{DebugMap, IterFormatExt, NoPretty};
+
+use crate::util::enumerate;
+use crate::visit::EdgeRef;
+use crate::visit::{IntoEdges, IntoEdgesDirected, IntoNodeReferences};
+
+#[cfg(feature = "serde-1")]
+mod serialization;
+
+/// The default integer type for graph indices.
+/// `u32` is the default to reduce the size of the graph's data and improve
+/// performance in the common case.
+///
+/// Used for node and edge indices in `Graph` and `StableGraph`, used
+/// for node indices in `Csr`.
+pub type DefaultIx = u32;
+
+/// Trait for the unsigned integer type used for node and edge indices.
+///
+/// Marked `unsafe` because: the trait must faithfully preserve
+/// and convert index values.
+pub unsafe trait IndexType: Copy + Default + Hash + Ord + fmt::Debug + 'static {
+ fn new(x: usize) -> Self;
+ fn index(&self) -> usize;
+ fn max() -> Self;
+}
+
+unsafe impl IndexType for usize {
+ #[inline(always)]
+ fn new(x: usize) -> Self {
+ x
+ }
+ #[inline(always)]
+ fn index(&self) -> Self {
+ *self
+ }
+ #[inline(always)]
+ fn max() -> Self {
+ ::std::usize::MAX
+ }
+}
+
+unsafe impl IndexType for u32 {
+ #[inline(always)]
+ fn new(x: usize) -> Self {
+ x as u32
+ }
+ #[inline(always)]
+ fn index(&self) -> usize {
+ *self as usize
+ }
+ #[inline(always)]
+ fn max() -> Self {
+ ::std::u32::MAX
+ }
+}
+
+unsafe impl IndexType for u16 {
+ #[inline(always)]
+ fn new(x: usize) -> Self {
+ x as u16
+ }
+ #[inline(always)]
+ fn index(&self) -> usize {
+ *self as usize
+ }
+ #[inline(always)]
+ fn max() -> Self {
+ ::std::u16::MAX
+ }
+}
+
+unsafe impl IndexType for u8 {
+ #[inline(always)]
+ fn new(x: usize) -> Self {
+ x as u8
+ }
+ #[inline(always)]
+ fn index(&self) -> usize {
+ *self as usize
+ }
+ #[inline(always)]
+ fn max() -> Self {
+ ::std::u8::MAX
+ }
+}
+
+/// Node identifier.
+#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
+pub struct NodeIndex<Ix = DefaultIx>(Ix);
+
+impl<Ix: IndexType> NodeIndex<Ix> {
+ #[inline]
+ pub fn new(x: usize) -> Self {
+ NodeIndex(IndexType::new(x))
+ }
+
+ #[inline]
+ pub fn index(self) -> usize {
+ self.0.index()
+ }
+
+ #[inline]
+ pub fn end() -> Self {
+ NodeIndex(IndexType::max())
+ }
+
+ fn _into_edge(self) -> EdgeIndex<Ix> {
+ EdgeIndex(self.0)
+ }
+}
+
+impl<Ix: IndexType> From<Ix> for NodeIndex<Ix> {
+ fn from(ix: Ix) -> Self {
+ NodeIndex(ix)
+ }
+}
+
+impl<Ix: fmt::Debug> fmt::Debug for NodeIndex<Ix> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "NodeIndex({:?})", self.0)
+ }
+}
+
+/// Short version of `NodeIndex::new`
+pub fn node_index<Ix: IndexType>(index: usize) -> NodeIndex<Ix> {
+ NodeIndex::new(index)
+}
+
+/// Short version of `EdgeIndex::new`
+pub fn edge_index<Ix: IndexType>(index: usize) -> EdgeIndex<Ix> {
+ EdgeIndex::new(index)
+}
+
+/// Edge identifier.
+#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
+pub struct EdgeIndex<Ix = DefaultIx>(Ix);
+
+impl<Ix: IndexType> EdgeIndex<Ix> {
+ #[inline]
+ pub fn new(x: usize) -> Self {
+ EdgeIndex(IndexType::new(x))
+ }
+
+ #[inline]
+ pub fn index(self) -> usize {
+ self.0.index()
+ }
+
+ /// An invalid `EdgeIndex` used to denote absence of an edge, for example
+ /// to end an adjacency list.
+ #[inline]
+ pub fn end() -> Self {
+ EdgeIndex(IndexType::max())
+ }
+
+ fn _into_node(self) -> NodeIndex<Ix> {
+ NodeIndex(self.0)
+ }
+}
+
+impl<Ix: IndexType> From<Ix> for EdgeIndex<Ix> {
+ fn from(ix: Ix) -> Self {
+ EdgeIndex(ix)
+ }
+}
+
+impl<Ix: fmt::Debug> fmt::Debug for EdgeIndex<Ix> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "EdgeIndex({:?})", self.0)
+ }
+}
+/*
+ * FIXME: Use this impl again, when we don't need to add so many bounds
+impl<Ix: IndexType> fmt::Debug for EdgeIndex<Ix>
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "EdgeIndex("));
+ if *self == EdgeIndex::end() {
+ try!(write!(f, "End"));
+ } else {
+ try!(write!(f, "{}", self.index()));
+ }
+ write!(f, ")")
+ }
+}
+*/
+
+const DIRECTIONS: [Direction; 2] = [Outgoing, Incoming];
+
+/// The graph's node type.
+#[derive(Debug)]
+pub struct Node<N, Ix = DefaultIx> {
+ /// Associated node data.
+ pub weight: N,
+ /// Next edge in outgoing and incoming edge lists.
+ next: [EdgeIndex<Ix>; 2],
+}
+
+impl<E, Ix> Clone for Node<E, Ix>
+where
+ E: Clone,
+ Ix: Copy,
+{
+ clone_fields!(Node, weight, next,);
+}
+
+impl<N, Ix: IndexType> Node<N, Ix> {
+ /// Accessor for data structure internals: the first edge in the given direction.
+ pub fn next_edge(&self, dir: Direction) -> EdgeIndex<Ix> {
+ self.next[dir.index()]
+ }
+}
+
+/// The graph's edge type.
+#[derive(Debug)]
+pub struct Edge<E, Ix = DefaultIx> {
+ /// Associated edge data.
+ pub weight: E,
+ /// Next edge in outgoing and incoming edge lists.
+ next: [EdgeIndex<Ix>; 2],
+ /// Start and End node index
+ node: [NodeIndex<Ix>; 2],
+}
+
+impl<E, Ix> Clone for Edge<E, Ix>
+where
+ E: Clone,
+ Ix: Copy,
+{
+ clone_fields!(Edge, weight, next, node,);
+}
+
+impl<E, Ix: IndexType> Edge<E, Ix> {
+ /// Accessor for data structure internals: the next edge for the given direction.
+ pub fn next_edge(&self, dir: Direction) -> EdgeIndex<Ix> {
+ self.next[dir.index()]
+ }
+
+ /// Return the source node index.
+ pub fn source(&self) -> NodeIndex<Ix> {
+ self.node[0]
+ }
+
+ /// Return the target node index.
+ pub fn target(&self) -> NodeIndex<Ix> {
+ self.node[1]
+ }
+}
+
+/// `Graph<N, E, Ty, Ix>` is a graph datastructure using an adjacency list representation.
+///
+/// `Graph` is parameterized over:
+///
+/// - Associated data `N` for nodes and `E` for edges, called *weights*.
+/// The associated data can be of arbitrary type.
+/// - Edge type `Ty` that determines whether the graph edges are directed or undirected.
+/// - Index type `Ix`, which determines the maximum size of the graph.
+///
+/// The `Graph` is a regular Rust collection and is `Send` and `Sync` (as long
+/// as associated data `N` and `E` are).
+///
+/// The graph uses **O(|V| + |E|)** space, and allows fast node and edge insert,
+/// efficient graph search and graph algorithms.
+/// It implements **O(e')** edge lookup and edge and node removals, where **e'**
+/// is some local measure of edge count.
+/// Based on the graph datastructure used in rustc.
+///
+/// Here's an example of building a graph with directed edges, and below
+/// an illustration of how it could be rendered with graphviz (see
+/// [`Dot`](../dot/struct.Dot.html)):
+///
+/// ```
+/// use petgraph::Graph;
+///
+/// let mut deps = Graph::<&str, &str>::new();
+/// let pg = deps.add_node("petgraph");
+/// let fb = deps.add_node("fixedbitset");
+/// let qc = deps.add_node("quickcheck");
+/// let rand = deps.add_node("rand");
+/// let libc = deps.add_node("libc");
+/// deps.extend_with_edges(&[
+/// (pg, fb), (pg, qc),
+/// (qc, rand), (rand, libc), (qc, libc),
+/// ]);
+/// ```
+///
+/// ![graph-example](https://bluss.github.io/ndarray/images/graph-example.svg)
+///
+/// ### Graph Indices
+///
+/// The graph maintains indices for nodes and edges, and node and edge
+/// weights may be accessed mutably. Indices range in a compact interval, for
+/// example for *n* nodes indices are 0 to *n* - 1 inclusive.
+///
+/// `NodeIndex` and `EdgeIndex` are types that act as references to nodes and edges,
+/// but these are only stable across certain operations:
+///
+/// * **Removing nodes or edges may shift other indices.** Removing a node will
+/// force the last node to shift its index to take its place. Similarly,
+/// removing an edge shifts the index of the last edge.
+/// * Adding nodes or edges keeps indices stable.
+///
+/// The `Ix` parameter is `u32` by default. The goal is that you can ignore this parameter
+/// completely unless you need a very big graph -- then you can use `usize`.
+///
+/// * The fact that the node and edge indices in the graph each are numbered in compact
+/// intervals (from 0 to *n* - 1 for *n* nodes) simplifies some graph algorithms.
+///
+/// * You can select graph index integer type after the size of the graph. A smaller
+/// size may have better performance.
+///
+/// * Using indices allows mutation while traversing the graph, see `Dfs`,
+/// and `.neighbors(a).detach()`.
+///
+/// * You can create several graphs using the equal node indices but with
+/// differing weights or differing edges.
+///
+/// * Indices don't allow as much compile time checking as references.
+///
+pub struct Graph<N, E, Ty = Directed, Ix = DefaultIx> {
+ nodes: Vec<Node<N, Ix>>,
+ edges: Vec<Edge<E, Ix>>,
+ ty: PhantomData<Ty>,
+}
+
+/// A `Graph` with directed edges.
+///
+/// For example, an edge from *1* to *2* is distinct from an edge from *2* to
+/// *1*.
+pub type DiGraph<N, E, Ix = DefaultIx> = Graph<N, E, Directed, Ix>;
+
+/// A `Graph` with undirected edges.
+///
+/// For example, an edge between *1* and *2* is equivalent to an edge between
+/// *2* and *1*.
+pub type UnGraph<N, E, Ix = DefaultIx> = Graph<N, E, Undirected, Ix>;
+
+/// The resulting cloned graph has the same graph indices as `self`.
+impl<N, E, Ty, Ix: IndexType> Clone for Graph<N, E, Ty, Ix>
+where
+ N: Clone,
+ E: Clone,
+{
+ fn clone(&self) -> Self {
+ Graph {
+ nodes: self.nodes.clone(),
+ edges: self.edges.clone(),
+ ty: self.ty,
+ }
+ }
+
+ fn clone_from(&mut self, rhs: &Self) {
+ self.nodes.clone_from(&rhs.nodes);
+ self.edges.clone_from(&rhs.edges);
+ self.ty = rhs.ty;
+ }
+}
+
+impl<N, E, Ty, Ix> fmt::Debug for Graph<N, E, Ty, Ix>
+where
+ N: fmt::Debug,
+ E: fmt::Debug,
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let etype = if self.is_directed() {
+ "Directed"
+ } else {
+ "Undirected"
+ };
+ let mut fmt_struct = f.debug_struct("Graph");
+ fmt_struct.field("Ty", &etype);
+ fmt_struct.field("node_count", &self.node_count());
+ fmt_struct.field("edge_count", &self.edge_count());
+ if self.edge_count() > 0 {
+ fmt_struct.field(
+ "edges",
+ &self
+ .edges
+ .iter()
+ .map(|e| NoPretty((e.source().index(), e.target().index())))
+ .format(", "),
+ );
+ }
+ // skip weights if they are ZST!
+ if size_of::<N>() != 0 {
+ fmt_struct.field(
+ "node weights",
+ &DebugMap(|| self.nodes.iter().map(|n| &n.weight).enumerate()),
+ );
+ }
+ if size_of::<E>() != 0 {
+ fmt_struct.field(
+ "edge weights",
+ &DebugMap(|| self.edges.iter().map(|n| &n.weight).enumerate()),
+ );
+ }
+ fmt_struct.finish()
+ }
+}
+
+enum Pair<T> {
+ Both(T, T),
+ One(T),
+ None,
+}
+
+use std::cmp::max;
+
+/// Get mutable references at index `a` and `b`.
+fn index_twice<T>(slc: &mut [T], a: usize, b: usize) -> Pair<&mut T> {
+ if max(a, b) >= slc.len() {
+ Pair::None
+ } else if a == b {
+ Pair::One(&mut slc[max(a, b)])
+ } else {
+ // safe because a, b are in bounds and distinct
+ unsafe {
+ let ar = &mut *(slc.get_unchecked_mut(a) as *mut _);
+ let br = &mut *(slc.get_unchecked_mut(b) as *mut _);
+ Pair::Both(ar, br)
+ }
+ }
+}
+
+impl<N, E> Graph<N, E, Directed> {
+ /// Create a new `Graph` with directed edges.
+ ///
+ /// This is a convenience method. Use `Graph::with_capacity` or `Graph::default` for
+ /// a constructor that is generic in all the type parameters of `Graph`.
+ pub fn new() -> Self {
+ Graph {
+ nodes: Vec::new(),
+ edges: Vec::new(),
+ ty: PhantomData,
+ }
+ }
+}
+
+impl<N, E> Graph<N, E, Undirected> {
+ /// Create a new `Graph` with undirected edges.
+ ///
+ /// This is a convenience method. Use `Graph::with_capacity` or `Graph::default` for
+ /// a constructor that is generic in all the type parameters of `Graph`.
+ pub fn new_undirected() -> Self {
+ Graph {
+ nodes: Vec::new(),
+ edges: Vec::new(),
+ ty: PhantomData,
+ }
+ }
+}
+
+impl<N, E, Ty, Ix> Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ /// Create a new `Graph` with estimated capacity.
+ pub fn with_capacity(nodes: usize, edges: usize) -> Self {
+ Graph {
+ nodes: Vec::with_capacity(nodes),
+ edges: Vec::with_capacity(edges),
+ ty: PhantomData,
+ }
+ }
+
+ /// Return the number of nodes (vertices) in the graph.
+ ///
+ /// Computes in **O(1)** time.
+ pub fn node_count(&self) -> usize {
+ self.nodes.len()
+ }
+
+ /// Return the number of edges in the graph.
+ ///
+ /// Computes in **O(1)** time.
+ pub fn edge_count(&self) -> usize {
+ self.edges.len()
+ }
+
+ /// Whether the graph has directed edges or not.
+ #[inline]
+ pub fn is_directed(&self) -> bool {
+ Ty::is_directed()
+ }
+
+ /// Add a node (also called vertex) with associated data `weight` to the graph.
+ ///
+ /// Computes in **O(1)** time.
+ ///
+ /// Return the index of the new node.
+ ///
+ /// **Panics** if the Graph is at the maximum number of nodes for its index
+ /// type (N/A if usize).
+ pub fn add_node(&mut self, weight: N) -> NodeIndex<Ix> {
+ let node = Node {
+ weight,
+ next: [EdgeIndex::end(), EdgeIndex::end()],
+ };
+ let node_idx = NodeIndex::new(self.nodes.len());
+ // check for max capacity, except if we use usize
+ assert!(<Ix as IndexType>::max().index() == !0 || NodeIndex::end() != node_idx);
+ self.nodes.push(node);
+ node_idx
+ }
+
+ /// Access the weight for node `a`.
+ ///
+ /// Also available with indexing syntax: `&graph[a]`.
+ pub fn node_weight(&self, a: NodeIndex<Ix>) -> Option<&N> {
+ self.nodes.get(a.index()).map(|n| &n.weight)
+ }
+
+ /// Access the weight for node `a`, mutably.
+ ///
+ /// Also available with indexing syntax: `&mut graph[a]`.
+ pub fn node_weight_mut(&mut self, a: NodeIndex<Ix>) -> Option<&mut N> {
+ self.nodes.get_mut(a.index()).map(|n| &mut n.weight)
+ }
+
+ /// Add an edge from `a` to `b` to the graph, with its associated
+ /// data `weight`.
+ ///
+ /// Return the index of the new edge.
+ ///
+ /// Computes in **O(1)** time.
+ ///
+ /// **Panics** if any of the nodes don't exist.<br>
+ /// **Panics** if the Graph is at the maximum number of edges for its index
+ /// type (N/A if usize).
+ ///
+ /// **Note:** `Graph` allows adding parallel (“duplicate”) edges. If you want
+ /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
+ pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
+ let edge_idx = EdgeIndex::new(self.edges.len());
+ assert!(<Ix as IndexType>::max().index() == !0 || EdgeIndex::end() != edge_idx);
+ let mut edge = Edge {
+ weight,
+ node: [a, b],
+ next: [EdgeIndex::end(); 2],
+ };
+ match index_twice(&mut self.nodes, a.index(), b.index()) {
+ Pair::None => panic!("Graph::add_edge: node indices out of bounds"),
+ Pair::One(an) => {
+ edge.next = an.next;
+ an.next[0] = edge_idx;
+ an.next[1] = edge_idx;
+ }
+ Pair::Both(an, bn) => {
+ // a and b are different indices
+ edge.next = [an.next[0], bn.next[1]];
+ an.next[0] = edge_idx;
+ bn.next[1] = edge_idx;
+ }
+ }
+ self.edges.push(edge);
+ edge_idx
+ }
+
+ /// Add or update an edge from `a` to `b`.
+ /// If the edge already exists, its weight is updated.
+ ///
+ /// Return the index of the affected edge.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of edges
+ /// connected to `a` (and `b`, if the graph edges are undirected).
+ ///
+ /// **Panics** if any of the nodes don't exist.
+ pub fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
+ if let Some(ix) = self.find_edge(a, b) {
+ if let Some(ed) = self.edge_weight_mut(ix) {
+ *ed = weight;
+ return ix;
+ }
+ }
+ self.add_edge(a, b, weight)
+ }
+
+ /// Access the weight for edge `e`.
+ ///
+ /// Also available with indexing syntax: `&graph[e]`.
+ pub fn edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E> {
+ self.edges.get(e.index()).map(|ed| &ed.weight)
+ }
+
+ /// Access the weight for edge `e`, mutably.
+ ///
+ /// Also available with indexing syntax: `&mut graph[e]`.
+ pub fn edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E> {
+ self.edges.get_mut(e.index()).map(|ed| &mut ed.weight)
+ }
+
+ /// Access the source and target nodes for `e`.
+ pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
+ self.edges
+ .get(e.index())
+ .map(|ed| (ed.source(), ed.target()))
+ }
+
+ /// Remove `a` from the graph if it exists, and return its weight.
+ /// If it doesn't exist in the graph, return `None`.
+ ///
+ /// Apart from `a`, this invalidates the last node index in the graph
+ /// (that node will adopt the removed node index). Edge indices are
+ /// invalidated as they would be following the removal of each edge
+ /// with an endpoint in `a`.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of affected
+ /// edges, including *n* calls to `.remove_edge()` where *n* is the number
+ /// of edges with an endpoint in `a`, and including the edges with an
+ /// endpoint in the displaced node.
+ pub fn remove_node(&mut self, a: NodeIndex<Ix>) -> Option<N> {
+ self.nodes.get(a.index())?;
+ for d in &DIRECTIONS {
+ let k = d.index();
+
+ // Remove all edges from and to this node.
+ loop {
+ let next = self.nodes[a.index()].next[k];
+ if next == EdgeIndex::end() {
+ break;
+ }
+ let ret = self.remove_edge(next);
+ debug_assert!(ret.is_some());
+ let _ = ret;
+ }
+ }
+
+ // Use swap_remove -- only the swapped-in node is going to change
+ // NodeIndex<Ix>, so we only have to walk its edges and update them.
+
+ let node = self.nodes.swap_remove(a.index());
+
+ // Find the edge lists of the node that had to relocate.
+ // It may be that no node had to relocate, then we are done already.
+ let swap_edges = match self.nodes.get(a.index()) {
+ None => return Some(node.weight),
+ Some(ed) => ed.next,
+ };
+
+ // The swapped element's old index
+ let old_index = NodeIndex::new(self.nodes.len());
+ let new_index = a;
+
+ // Adjust the starts of the out edges, and ends of the in edges.
+ for &d in &DIRECTIONS {
+ let k = d.index();
+ let mut edges = edges_walker_mut(&mut self.edges, swap_edges[k], d);
+ while let Some(curedge) = edges.next_edge() {
+ debug_assert!(curedge.node[k] == old_index);
+ curedge.node[k] = new_index;
+ }
+ }
+ Some(node.weight)
+ }
+
+ /// For edge `e` with endpoints `edge_node`, replace links to it,
+ /// with links to `edge_next`.
+ fn change_edge_links(
+ &mut self,
+ edge_node: [NodeIndex<Ix>; 2],
+ e: EdgeIndex<Ix>,
+ edge_next: [EdgeIndex<Ix>; 2],
+ ) {
+ for &d in &DIRECTIONS {
+ let k = d.index();
+ let node = match self.nodes.get_mut(edge_node[k].index()) {
+ Some(r) => r,
+ None => {
+ debug_assert!(
+ false,
+ "Edge's endpoint dir={:?} index={:?} not found",
+ d, edge_node[k]
+ );
+ return;
+ }
+ };
+ let fst = node.next[k];
+ if fst == e {
+ //println!("Updating first edge 0 for node {}, set to {}", edge_node[0], edge_next[0]);
+ node.next[k] = edge_next[k];
+ } else {
+ let mut edges = edges_walker_mut(&mut self.edges, fst, d);
+ while let Some(curedge) = edges.next_edge() {
+ if curedge.next[k] == e {
+ curedge.next[k] = edge_next[k];
+ break; // the edge can only be present once in the list.
+ }
+ }
+ }
+ }
+ }
+
+ /// Remove an edge and return its edge weight, or `None` if it didn't exist.
+ ///
+ /// Apart from `e`, this invalidates the last edge index in the graph
+ /// (that edge will adopt the removed edge index).
+ ///
+ /// Computes in **O(e')** time, where **e'** is the size of four particular edge lists, for
+ /// the vertices of `e` and the vertices of another affected edge.
+ pub fn remove_edge(&mut self, e: EdgeIndex<Ix>) -> Option<E> {
+ // every edge is part of two lists,
+ // outgoing and incoming edges.
+ // Remove it from both
+ let (edge_node, edge_next) = match self.edges.get(e.index()) {
+ None => return None,
+ Some(x) => (x.node, x.next),
+ };
+ // Remove the edge from its in and out lists by replacing it with
+ // a link to the next in the list.
+ self.change_edge_links(edge_node, e, edge_next);
+ self.remove_edge_adjust_indices(e)
+ }
+
+ fn remove_edge_adjust_indices(&mut self, e: EdgeIndex<Ix>) -> Option<E> {
+ // swap_remove the edge -- only the removed edge
+ // and the edge swapped into place are affected and need updating
+ // indices.
+ let edge = self.edges.swap_remove(e.index());
+ let swap = match self.edges.get(e.index()) {
+ // no elment needed to be swapped.
+ None => return Some(edge.weight),
+ Some(ed) => ed.node,
+ };
+ let swapped_e = EdgeIndex::new(self.edges.len());
+
+ // Update the edge lists by replacing links to the old index by references to the new
+ // edge index.
+ self.change_edge_links(swap, swapped_e, [e, e]);
+ Some(edge.weight)
+ }
+
+ /// Return an iterator of all nodes with an edge starting from `a`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges from or to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `NodeIndex<Ix>`.
+ ///
+ /// Use [`.neighbors(a).detach()`][1] to get a neighbor walker that does
+ /// not borrow from the graph.
+ ///
+ /// [1]: struct.Neighbors.html#method.detach
+ pub fn neighbors(&self, a: NodeIndex<Ix>) -> Neighbors<E, Ix> {
+ self.neighbors_directed(a, Outgoing)
+ }
+
+ /// Return an iterator of all neighbors that have an edge between them and
+ /// `a`, in the specified direction.
+ /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*.
+ ///
+ /// - `Directed`, `Outgoing`: All edges from `a`.
+ /// - `Directed`, `Incoming`: All edges to `a`.
+ /// - `Undirected`: All edges from or to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `NodeIndex<Ix>`.
+ ///
+ /// For a `Directed` graph, neighbors are listed in reverse order of their
+ /// addition to the graph, so the most recently added edge's neighbor is
+ /// listed first. The order in an `Undirected` graph is arbitrary.
+ ///
+ /// Use [`.neighbors_directed(a, dir).detach()`][1] to get a neighbor walker that does
+ /// not borrow from the graph.
+ ///
+ /// [1]: struct.Neighbors.html#method.detach
+ pub fn neighbors_directed(&self, a: NodeIndex<Ix>, dir: Direction) -> Neighbors<E, Ix> {
+ let mut iter = self.neighbors_undirected(a);
+ if self.is_directed() {
+ let k = dir.index();
+ iter.next[1 - k] = EdgeIndex::end();
+ iter.skip_start = NodeIndex::end();
+ }
+ iter
+ }
+
+ /// Return an iterator of all neighbors that have an edge between them and
+ /// `a`, in either direction.
+ /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*.
+ ///
+ /// - `Directed` and `Undirected`: All edges from or to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `NodeIndex<Ix>`.
+ ///
+ /// Use [`.neighbors_undirected(a).detach()`][1] to get a neighbor walker that does
+ /// not borrow from the graph.
+ ///
+ /// [1]: struct.Neighbors.html#method.detach
+ ///
+ pub fn neighbors_undirected(&self, a: NodeIndex<Ix>) -> Neighbors<E, Ix> {
+ Neighbors {
+ skip_start: a,
+ edges: &self.edges,
+ next: match self.nodes.get(a.index()) {
+ None => [EdgeIndex::end(), EdgeIndex::end()],
+ Some(n) => n.next,
+ },
+ }
+ }
+
+ /// Return an iterator of all edges of `a`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges connected to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `EdgeReference<E, Ix>`.
+ pub fn edges(&self, a: NodeIndex<Ix>) -> Edges<E, Ty, Ix> {
+ self.edges_directed(a, Outgoing)
+ }
+
+ /// Return an iterator of all edges of `a`, in the specified direction.
+ ///
+ /// - `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.
+ ///
+ /// Produces an empty iterator if the node `a` doesn't exist.<br>
+ /// Iterator element type is `EdgeReference<E, Ix>`.
+ pub fn edges_directed(&self, a: NodeIndex<Ix>, dir: Direction) -> Edges<E, Ty, Ix> {
+ Edges {
+ skip_start: a,
+ edges: &self.edges,
+ direction: dir,
+ next: match self.nodes.get(a.index()) {
+ None => [EdgeIndex::end(), EdgeIndex::end()],
+ Some(n) => n.next,
+ },
+ ty: PhantomData,
+ }
+ }
+
+ /// Return an iterator over all the edges connecting `a` and `b`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges connected to `a`.
+ ///
+ /// Iterator element type is `EdgeReference<E, Ix>`.
+ pub fn edges_connecting(
+ &self,
+ a: NodeIndex<Ix>,
+ b: NodeIndex<Ix>,
+ ) -> EdgesConnecting<E, Ty, Ix> {
+ EdgesConnecting {
+ target_node: b,
+ edges: self.edges_directed(a, Direction::Outgoing),
+ ty: PhantomData,
+ }
+ }
+
+ /// Lookup if there is an edge from `a` to `b`.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of edges
+ /// connected to `a` (and `b`, if the graph edges are undirected).
+ pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
+ self.find_edge(a, b).is_some()
+ }
+
+ /// Lookup an edge from `a` to `b`.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of edges
+ /// connected to `a` (and `b`, if the graph edges are undirected).
+ pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
+ if !self.is_directed() {
+ self.find_edge_undirected(a, b).map(|(ix, _)| ix)
+ } else {
+ match self.nodes.get(a.index()) {
+ None => None,
+ Some(node) => self.find_edge_directed_from_node(node, b),
+ }
+ }
+ }
+
+ fn find_edge_directed_from_node(
+ &self,
+ node: &Node<N, Ix>,
+ b: NodeIndex<Ix>,
+ ) -> Option<EdgeIndex<Ix>> {
+ let mut edix = node.next[0];
+ while let Some(edge) = self.edges.get(edix.index()) {
+ if edge.node[1] == b {
+ return Some(edix);
+ }
+ edix = edge.next[0];
+ }
+ None
+ }
+
+ /// Lookup an edge between `a` and `b`, in either direction.
+ ///
+ /// If the graph is undirected, then this is equivalent to `.find_edge()`.
+ ///
+ /// Return the edge index and its directionality, with `Outgoing` meaning
+ /// from `a` to `b` and `Incoming` the reverse,
+ /// or `None` if the edge does not exist.
+ pub fn find_edge_undirected(
+ &self,
+ a: NodeIndex<Ix>,
+ b: NodeIndex<Ix>,
+ ) -> Option<(EdgeIndex<Ix>, Direction)> {
+ match self.nodes.get(a.index()) {
+ None => None,
+ Some(node) => self.find_edge_undirected_from_node(node, b),
+ }
+ }
+
+ fn find_edge_undirected_from_node(
+ &self,
+ node: &Node<N, Ix>,
+ b: NodeIndex<Ix>,
+ ) -> Option<(EdgeIndex<Ix>, Direction)> {
+ for &d in &DIRECTIONS {
+ let k = d.index();
+ let mut edix = node.next[k];
+ while let Some(edge) = self.edges.get(edix.index()) {
+ if edge.node[1 - k] == b {
+ return Some((edix, d));
+ }
+ edix = edge.next[k];
+ }
+ }
+ None
+ }
+
+ /// Return an iterator over either the nodes without edges to them
+ /// (`Incoming`) or from them (`Outgoing`).
+ ///
+ /// An *internal* node has both incoming and outgoing edges.
+ /// The nodes in `.externals(Incoming)` are the source nodes and
+ /// `.externals(Outgoing)` are the sinks of the graph.
+ ///
+ /// For a graph with undirected edges, both the sinks and the sources are
+ /// just the nodes without edges.
+ ///
+ /// The whole iteration computes in **O(|V|)** time.
+ pub fn externals(&self, dir: Direction) -> Externals<N, Ty, Ix> {
+ Externals {
+ iter: self.nodes.iter().enumerate(),
+ dir,
+ ty: PhantomData,
+ }
+ }
+
+ /// Return an iterator over the node indices of the graph.
+ ///
+ /// For example, in a rare case where a graph algorithm were not applicable,
+ /// the following code will iterate through all nodes to find a
+ /// specific index:
+ ///
+ /// ```
+ /// # use petgraph::Graph;
+ /// # let mut g = Graph::<&str, i32>::new();
+ /// # g.add_node("book");
+ /// let index = g.node_indices().find(|i| g[*i] == "book").unwrap();
+ /// ```
+ pub fn node_indices(&self) -> NodeIndices<Ix> {
+ NodeIndices {
+ r: 0..self.node_count(),
+ ty: PhantomData,
+ }
+ }
+
+ /// Return an iterator yielding mutable access to all node weights.
+ ///
+ /// The order in which weights are yielded matches the order of their
+ /// node indices.
+ pub fn node_weights_mut(&mut self) -> NodeWeightsMut<N, Ix> {
+ NodeWeightsMut {
+ nodes: self.nodes.iter_mut(),
+ }
+ }
+
+ /// Return an iterator over the edge indices of the graph
+ pub fn edge_indices(&self) -> EdgeIndices<Ix> {
+ EdgeIndices {
+ r: 0..self.edge_count(),
+ ty: PhantomData,
+ }
+ }
+
+ /// Create an iterator over all edges, in indexed order.
+ ///
+ /// Iterator element type is `EdgeReference<E, Ix>`.
+ pub fn edge_references(&self) -> EdgeReferences<E, Ix> {
+ EdgeReferences {
+ iter: self.edges.iter().enumerate(),
+ }
+ }
+
+ /// Return an iterator yielding mutable access to all edge weights.
+ ///
+ /// The order in which weights are yielded matches the order of their
+ /// edge indices.
+ pub fn edge_weights_mut(&mut self) -> EdgeWeightsMut<E, Ix> {
+ EdgeWeightsMut {
+ edges: self.edges.iter_mut(),
+ }
+ }
+
+ // Remaining methods are of the more internal flavour, read-only access to
+ // the data structure's internals.
+
+ /// Access the internal node array.
+ pub fn raw_nodes(&self) -> &[Node<N, Ix>] {
+ &self.nodes
+ }
+
+ /// Access the internal edge array.
+ pub fn raw_edges(&self) -> &[Edge<E, Ix>] {
+ &self.edges
+ }
+
+ /// Convert the graph into a vector of Nodes and a vector of Edges
+ pub fn into_nodes_edges(self) -> (Vec<Node<N, Ix>>, Vec<Edge<E, Ix>>) {
+ (self.nodes, self.edges)
+ }
+
+ /// Accessor for data structure internals: the first edge in the given direction.
+ pub fn first_edge(&self, a: NodeIndex<Ix>, dir: Direction) -> Option<EdgeIndex<Ix>> {
+ match self.nodes.get(a.index()) {
+ None => None,
+ Some(node) => {
+ let edix = node.next[dir.index()];
+ if edix == EdgeIndex::end() {
+ None
+ } else {
+ Some(edix)
+ }
+ }
+ }
+ }
+
+ /// Accessor for data structure internals: the next edge for the given direction.
+ pub fn next_edge(&self, e: EdgeIndex<Ix>, dir: Direction) -> Option<EdgeIndex<Ix>> {
+ match self.edges.get(e.index()) {
+ None => None,
+ Some(node) => {
+ let edix = node.next[dir.index()];
+ if edix == EdgeIndex::end() {
+ None
+ } else {
+ Some(edix)
+ }
+ }
+ }
+ }
+
+ /// Index the `Graph` by two indices, any combination of
+ /// node or edge indices is fine.
+ ///
+ /// **Panics** if the indices are equal or if they are out of bounds.
+ ///
+ /// ```
+ /// use petgraph::{Graph, Incoming};
+ /// use petgraph::visit::Dfs;
+ ///
+ /// let mut gr = Graph::new();
+ /// let a = gr.add_node(0.);
+ /// let b = gr.add_node(0.);
+ /// let c = gr.add_node(0.);
+ /// gr.add_edge(a, b, 3.);
+ /// gr.add_edge(b, c, 2.);
+ /// gr.add_edge(c, b, 1.);
+ ///
+ /// // walk the graph and sum incoming edges into the node weight
+ /// let mut dfs = Dfs::new(&gr, a);
+ /// while let Some(node) = dfs.next(&gr) {
+ /// // use a walker -- a detached neighbors iterator
+ /// let mut edges = gr.neighbors_directed(node, Incoming).detach();
+ /// while let Some(edge) = edges.next_edge(&gr) {
+ /// let (nw, ew) = gr.index_twice_mut(node, edge);
+ /// *nw += *ew;
+ /// }
+ /// }
+ ///
+ /// // check the result
+ /// assert_eq!(gr[a], 0.);
+ /// assert_eq!(gr[b], 4.);
+ /// assert_eq!(gr[c], 2.);
+ /// ```
+ pub fn index_twice_mut<T, U>(
+ &mut self,
+ i: T,
+ j: U,
+ ) -> (
+ &mut <Self as Index<T>>::Output,
+ &mut <Self as Index<U>>::Output,
+ )
+ where
+ Self: IndexMut<T> + IndexMut<U>,
+ T: GraphIndex,
+ U: GraphIndex,
+ {
+ assert!(T::is_node_index() != U::is_node_index() || i.index() != j.index());
+
+ // Allow two mutable indexes here -- they are nonoverlapping
+ unsafe {
+ let self_mut = self as *mut _;
+ (
+ <Self as IndexMut<T>>::index_mut(&mut *self_mut, i),
+ <Self as IndexMut<U>>::index_mut(&mut *self_mut, j),
+ )
+ }
+ }
+
+ /// Reverse the direction of all edges
+ pub fn reverse(&mut self) {
+ // swap edge endpoints,
+ // edge incoming / outgoing lists,
+ // node incoming / outgoing lists
+ for edge in &mut self.edges {
+ edge.node.swap(0, 1);
+ edge.next.swap(0, 1);
+ }
+ for node in &mut self.nodes {
+ node.next.swap(0, 1);
+ }
+ }
+
+ /// Remove all nodes and edges
+ pub fn clear(&mut self) {
+ self.nodes.clear();
+ self.edges.clear();
+ }
+
+ /// Remove all edges
+ pub fn clear_edges(&mut self) {
+ self.edges.clear();
+ for node in &mut self.nodes {
+ node.next = [EdgeIndex::end(), EdgeIndex::end()];
+ }
+ }
+
+ /// Return the current node and edge capacity of the graph.
+ pub fn capacity(&self) -> (usize, usize) {
+ (self.nodes.capacity(), self.edges.capacity())
+ }
+
+ /// Reserves capacity for at least `additional` more nodes to be inserted in
+ /// the graph. Graph may reserve more space to avoid frequent reallocations.
+ ///
+ /// **Panics** if the new capacity overflows `usize`.
+ pub fn reserve_nodes(&mut self, additional: usize) {
+ self.nodes.reserve(additional);
+ }
+
+ /// Reserves capacity for at least `additional` more edges to be inserted in
+ /// the graph. Graph may reserve more space to avoid frequent reallocations.
+ ///
+ /// **Panics** if the new capacity overflows `usize`.
+ pub fn reserve_edges(&mut self, additional: usize) {
+ self.edges.reserve(additional);
+ }
+
+ /// Reserves the minimum capacity for exactly `additional` more nodes to be
+ /// inserted in the graph. Does nothing if the capacity is already
+ /// sufficient.
+ ///
+ /// Prefer `reserve_nodes` if future insertions are expected.
+ ///
+ /// **Panics** if the new capacity overflows `usize`.
+ pub fn reserve_exact_nodes(&mut self, additional: usize) {
+ self.nodes.reserve_exact(additional);
+ }
+
+ /// Reserves the minimum capacity for exactly `additional` more edges to be
+ /// inserted in the graph.
+ /// Does nothing if the capacity is already sufficient.
+ ///
+ /// Prefer `reserve_edges` if future insertions are expected.
+ ///
+ /// **Panics** if the new capacity overflows `usize`.
+ pub fn reserve_exact_edges(&mut self, additional: usize) {
+ self.edges.reserve_exact(additional);
+ }
+
+ /// Shrinks the capacity of the underlying nodes collection as much as possible.
+ pub fn shrink_to_fit_nodes(&mut self) {
+ self.nodes.shrink_to_fit();
+ }
+
+ /// Shrinks the capacity of the underlying edges collection as much as possible.
+ pub fn shrink_to_fit_edges(&mut self) {
+ self.edges.shrink_to_fit();
+ }
+
+ /// Shrinks the capacity of the graph as much as possible.
+ pub fn shrink_to_fit(&mut self) {
+ self.nodes.shrink_to_fit();
+ self.edges.shrink_to_fit();
+ }
+
+ /// Keep all nodes that return `true` from the `visit` closure,
+ /// remove the others.
+ ///
+ /// `visit` is provided a proxy reference to the graph, so that
+ /// the graph can be walked and associated data modified.
+ ///
+ /// The order nodes are visited is not specified.
+ pub fn retain_nodes<F>(&mut self, mut visit: F)
+ where
+ F: FnMut(Frozen<Self>, NodeIndex<Ix>) -> bool,
+ {
+ for index in self.node_indices().rev() {
+ if !visit(Frozen(self), index) {
+ let ret = self.remove_node(index);
+ debug_assert!(ret.is_some());
+ let _ = ret;
+ }
+ }
+ }
+
+ /// Keep all edges that return `true` from the `visit` closure,
+ /// remove the others.
+ ///
+ /// `visit` is provided a proxy reference to the graph, so that
+ /// the graph can be walked and associated data modified.
+ ///
+ /// The order edges are visited is not specified.
+ pub fn retain_edges<F>(&mut self, mut visit: F)
+ where
+ F: FnMut(Frozen<Self>, EdgeIndex<Ix>) -> bool,
+ {
+ for index in self.edge_indices().rev() {
+ if !visit(Frozen(self), index) {
+ let ret = self.remove_edge(index);
+ debug_assert!(ret.is_some());
+ let _ = ret;
+ }
+ }
+ }
+
+ /// Create a new `Graph` from an iterable of edges.
+ ///
+ /// Node weights `N` are set to default values.
+ /// Edge weights `E` may either be specified in the list,
+ /// or they are filled with default values.
+ ///
+ /// Nodes are inserted automatically to match the edges.
+ ///
+ /// ```
+ /// use petgraph::Graph;
+ ///
+ /// let gr = Graph::<(), i32>::from_edges(&[
+ /// (0, 1), (0, 2), (0, 3),
+ /// (1, 2), (1, 3),
+ /// (2, 3),
+ /// ]);
+ /// ```
+ pub fn from_edges<I>(iterable: I) -> Self
+ where
+ I: IntoIterator,
+ I::Item: IntoWeightedEdge<E>,
+ <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
+ N: Default,
+ {
+ let mut g = Self::with_capacity(0, 0);
+ g.extend_with_edges(iterable);
+ g
+ }
+
+ /// Extend the graph from an iterable of edges.
+ ///
+ /// Node weights `N` are set to default values.
+ /// Edge weights `E` may either be specified in the list,
+ /// or they are filled with default values.
+ ///
+ /// Nodes are inserted automatically to match the edges.
+ pub fn extend_with_edges<I>(&mut self, iterable: I)
+ where
+ I: IntoIterator,
+ I::Item: IntoWeightedEdge<E>,
+ <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
+ N: Default,
+ {
+ let iter = iterable.into_iter();
+ let (low, _) = iter.size_hint();
+ self.edges.reserve(low);
+
+ for elt in iter {
+ let (source, target, weight) = elt.into_weighted_edge();
+ let (source, target) = (source.into(), target.into());
+ let nx = cmp::max(source, target);
+ while nx.index() >= self.node_count() {
+ self.add_node(N::default());
+ }
+ self.add_edge(source, target, weight);
+ }
+ }
+
+ /// Create a new `Graph` by mapping node and
+ /// edge weights to new values.
+ ///
+ /// The resulting graph has the same structure and the same
+ /// graph indices as `self`.
+ pub fn map<'a, F, G, N2, E2>(
+ &'a self,
+ mut node_map: F,
+ mut edge_map: G,
+ ) -> Graph<N2, E2, Ty, Ix>
+ where
+ F: FnMut(NodeIndex<Ix>, &'a N) -> N2,
+ G: FnMut(EdgeIndex<Ix>, &'a E) -> E2,
+ {
+ let mut g = Graph::with_capacity(self.node_count(), self.edge_count());
+ g.nodes.extend(enumerate(&self.nodes).map(|(i, node)| Node {
+ weight: node_map(NodeIndex::new(i), &node.weight),
+ next: node.next,
+ }));
+ g.edges.extend(enumerate(&self.edges).map(|(i, edge)| Edge {
+ weight: edge_map(EdgeIndex::new(i), &edge.weight),
+ next: edge.next,
+ node: edge.node,
+ }));
+ g
+ }
+
+ /// Create a new `Graph` by mapping nodes and edges.
+ /// A node or edge may be mapped to `None` to exclude it from
+ /// the resulting graph.
+ ///
+ /// Nodes are mapped first with the `node_map` closure, then
+ /// `edge_map` is called for the edges that have not had any endpoint
+ /// removed.
+ ///
+ /// The resulting graph has the structure of a subgraph of the original graph.
+ /// If no nodes are removed, the resulting graph has compatible node
+ /// indices; if neither nodes nor edges are removed, the result has
+ /// the same graph indices as `self`.
+ pub fn filter_map<'a, F, G, N2, E2>(
+ &'a self,
+ mut node_map: F,
+ mut edge_map: G,
+ ) -> Graph<N2, E2, Ty, Ix>
+ where
+ F: FnMut(NodeIndex<Ix>, &'a N) -> Option<N2>,
+ G: FnMut(EdgeIndex<Ix>, &'a E) -> Option<E2>,
+ {
+ let mut g = Graph::with_capacity(0, 0);
+ // mapping from old node index to new node index, end represents removed.
+ let mut node_index_map = vec![NodeIndex::end(); self.node_count()];
+ for (i, node) in enumerate(&self.nodes) {
+ if let Some(nw) = node_map(NodeIndex::new(i), &node.weight) {
+ node_index_map[i] = g.add_node(nw);
+ }
+ }
+ for (i, edge) in enumerate(&self.edges) {
+ // skip edge if any endpoint was removed
+ let source = node_index_map[edge.source().index()];
+ let target = node_index_map[edge.target().index()];
+ if source != NodeIndex::end() && target != NodeIndex::end() {
+ if let Some(ew) = edge_map(EdgeIndex::new(i), &edge.weight) {
+ g.add_edge(source, target, ew);
+ }
+ }
+ }
+ g
+ }
+
+ /// Convert the graph into either undirected or directed. No edge adjustments
+ /// are done, so you may want to go over the result to remove or add edges.
+ ///
+ /// Computes in **O(1)** time.
+ pub fn into_edge_type<NewTy>(self) -> Graph<N, E, NewTy, Ix>
+ where
+ NewTy: EdgeType,
+ {
+ Graph {
+ nodes: self.nodes,
+ edges: self.edges,
+ ty: PhantomData,
+ }
+ }
+
+ //
+ // internal methods
+ //
+ #[cfg(feature = "serde-1")]
+ /// Fix up node and edge links after deserialization
+ fn link_edges(&mut self) -> Result<(), NodeIndex<Ix>> {
+ for (edge_index, edge) in enumerate(&mut self.edges) {
+ let a = edge.source();
+ let b = edge.target();
+ let edge_idx = EdgeIndex::new(edge_index);
+ match index_twice(&mut self.nodes, a.index(), b.index()) {
+ Pair::None => return Err(if a > b { a } else { b }),
+ Pair::One(an) => {
+ edge.next = an.next;
+ an.next[0] = edge_idx;
+ an.next[1] = edge_idx;
+ }
+ Pair::Both(an, bn) => {
+ // a and b are different indices
+ edge.next = [an.next[0], bn.next[1]];
+ an.next[0] = edge_idx;
+ bn.next[1] = edge_idx;
+ }
+ }
+ }
+ Ok(())
+ }
+}
+
+/// An iterator over either the nodes without edges to them or from them.
+pub struct Externals<'a, N: 'a, Ty, Ix: IndexType = DefaultIx> {
+ iter: iter::Enumerate<slice::Iter<'a, Node<N, Ix>>>,
+ dir: Direction,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, N: 'a, Ty, Ix> Iterator for Externals<'a, N, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Item = NodeIndex<Ix>;
+ fn next(&mut self) -> Option<NodeIndex<Ix>> {
+ let k = self.dir.index();
+ loop {
+ match self.iter.next() {
+ None => return None,
+ Some((index, node)) => {
+ if node.next[k] == EdgeIndex::end()
+ && (Ty::is_directed() || node.next[1 - k] == EdgeIndex::end())
+ {
+ return Some(NodeIndex::new(index));
+ } else {
+ continue;
+ }
+ }
+ }
+ }
+ }
+}
+
+/// Iterator over the neighbors of a node.
+///
+/// Iterator element type is `NodeIndex<Ix>`.
+///
+/// Created with [`.neighbors()`][1], [`.neighbors_directed()`][2] or
+/// [`.neighbors_undirected()`][3].
+///
+/// [1]: struct.Graph.html#method.neighbors
+/// [2]: struct.Graph.html#method.neighbors_directed
+/// [3]: struct.Graph.html#method.neighbors_undirected
+pub struct Neighbors<'a, E: 'a, Ix: 'a = DefaultIx> {
+ /// starting node to skip over
+ skip_start: NodeIndex<Ix>,
+ edges: &'a [Edge<E, Ix>],
+ next: [EdgeIndex<Ix>; 2],
+}
+
+impl<'a, E, Ix> Iterator for Neighbors<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = NodeIndex<Ix>;
+
+ fn next(&mut self) -> Option<NodeIndex<Ix>> {
+ // First any outgoing edges
+ match self.edges.get(self.next[0].index()) {
+ None => {}
+ Some(edge) => {
+ self.next[0] = edge.next[0];
+ return Some(edge.node[1]);
+ }
+ }
+ // Then incoming edges
+ // For an "undirected" iterator (traverse both incoming
+ // and outgoing edge lists), make sure we don't double
+ // count selfloops by skipping them in the incoming list.
+ while let Some(edge) = self.edges.get(self.next[1].index()) {
+ self.next[1] = edge.next[1];
+ if edge.node[0] != self.skip_start {
+ return Some(edge.node[0]);
+ }
+ }
+ None
+ }
+}
+
+impl<'a, E, Ix> Clone for Neighbors<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ clone_fields!(Neighbors, skip_start, edges, next,);
+}
+
+impl<'a, E, Ix> Neighbors<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ /// Return a “walker” object that can be used to step through the
+ /// neighbors and edges from the origin node.
+ ///
+ /// Note: The walker does not borrow from the graph, this is to allow mixing
+ /// edge walking with mutating the graph's weights.
+ pub fn detach(&self) -> WalkNeighbors<Ix> {
+ WalkNeighbors {
+ skip_start: self.skip_start,
+ next: self.next,
+ }
+ }
+}
+
+struct EdgesWalkerMut<'a, E: 'a, Ix: IndexType = DefaultIx> {
+ edges: &'a mut [Edge<E, Ix>],
+ next: EdgeIndex<Ix>,
+ dir: Direction,
+}
+
+fn edges_walker_mut<E, Ix>(
+ edges: &mut [Edge<E, Ix>],
+ next: EdgeIndex<Ix>,
+ dir: Direction,
+) -> EdgesWalkerMut<E, Ix>
+where
+ Ix: IndexType,
+{
+ EdgesWalkerMut { edges, next, dir }
+}
+
+impl<'a, E, Ix> EdgesWalkerMut<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ fn next_edge(&mut self) -> Option<&mut Edge<E, Ix>> {
+ self.next().map(|t| t.1)
+ }
+
+ fn next(&mut self) -> Option<(EdgeIndex<Ix>, &mut Edge<E, Ix>)> {
+ let this_index = self.next;
+ let k = self.dir.index();
+ match self.edges.get_mut(self.next.index()) {
+ None => None,
+ Some(edge) => {
+ self.next = edge.next[k];
+ Some((this_index, edge))
+ }
+ }
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoEdges for &'a Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Edges = Edges<'a, E, Ty, Ix>;
+ fn edges(self, a: Self::NodeId) -> Self::Edges {
+ self.edges(a)
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoEdgesDirected for &'a Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type EdgesDirected = Edges<'a, E, Ty, Ix>;
+ fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected {
+ self.edges_directed(a, dir)
+ }
+}
+
+/// Iterator over the edges of from or to a node
+pub struct Edges<'a, E: 'a, Ty, Ix: 'a = DefaultIx>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ /// starting node to skip over
+ skip_start: NodeIndex<Ix>,
+ edges: &'a [Edge<E, Ix>],
+
+ /// Next edge to visit.
+ next: [EdgeIndex<Ix>; 2],
+
+ /// For directed graphs: the direction to iterate in
+ /// For undirected graphs: the direction of edges
+ direction: Direction,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, E, Ty, Ix> Iterator for Edges<'a, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Item = EdgeReference<'a, E, Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ // type direction | iterate over reverse
+ // |
+ // Directed Outgoing | outgoing no
+ // Directed Incoming | incoming no
+ // Undirected Outgoing | both incoming
+ // Undirected Incoming | both outgoing
+
+ // For iterate_over, "both" is represented as None.
+ // For reverse, "no" is represented as None.
+ let (iterate_over, reverse) = if Ty::is_directed() {
+ (Some(self.direction), None)
+ } else {
+ (None, Some(self.direction.opposite()))
+ };
+
+ if iterate_over.unwrap_or(Outgoing) == Outgoing {
+ let i = self.next[0].index();
+ if let Some(Edge { node, weight, next }) = self.edges.get(i) {
+ self.next[0] = next[0];
+ return Some(EdgeReference {
+ index: edge_index(i),
+ node: if reverse == Some(Outgoing) {
+ swap_pair(*node)
+ } else {
+ *node
+ },
+ weight,
+ });
+ }
+ }
+
+ if iterate_over.unwrap_or(Incoming) == Incoming {
+ while let Some(Edge { node, weight, next }) = self.edges.get(self.next[1].index()) {
+ let edge_index = self.next[1];
+ self.next[1] = next[1];
+ // In any of the "both" situations, self-loops would be iterated over twice.
+ // Skip them here.
+ if iterate_over.is_none() && node[0] == self.skip_start {
+ continue;
+ }
+
+ return Some(EdgeReference {
+ index: edge_index,
+ node: if reverse == Some(Incoming) {
+ swap_pair(*node)
+ } else {
+ *node
+ },
+ weight,
+ });
+ }
+ }
+
+ None
+ }
+}
+
+/// Iterator over the multiple directed edges connecting a source node to a target node
+pub struct EdgesConnecting<'a, E: 'a, Ty, Ix: 'a = DefaultIx>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ target_node: NodeIndex<Ix>,
+ edges: Edges<'a, E, Ty, Ix>,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, E, Ty, Ix> Iterator for EdgesConnecting<'a, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Item = EdgeReference<'a, E, Ix>;
+
+ fn next(&mut self) -> Option<EdgeReference<'a, E, Ix>> {
+ while let Some(edge) = self.edges.next() {
+ if edge.node[1] == self.target_node {
+ return Some(edge);
+ }
+ }
+
+ None
+ }
+}
+
+fn swap_pair<T>(mut x: [T; 2]) -> [T; 2] {
+ x.swap(0, 1);
+ x
+}
+
+impl<'a, E, Ty, Ix> Clone for Edges<'a, E, Ty, Ix>
+where
+ Ix: IndexType,
+ Ty: EdgeType,
+{
+ fn clone(&self) -> Self {
+ Edges {
+ skip_start: self.skip_start,
+ edges: self.edges,
+ next: self.next,
+ direction: self.direction,
+ ty: self.ty,
+ }
+ }
+}
+
+/// Iterator yielding mutable access to all node weights.
+pub struct NodeWeightsMut<'a, N: 'a, Ix: IndexType = DefaultIx> {
+ nodes: ::std::slice::IterMut<'a, Node<N, Ix>>,
+}
+
+impl<'a, N, Ix> Iterator for NodeWeightsMut<'a, N, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = &'a mut N;
+
+ fn next(&mut self) -> Option<&'a mut N> {
+ self.nodes.next().map(|node| &mut node.weight)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.nodes.size_hint()
+ }
+}
+
+/// Iterator yielding mutable access to all edge weights.
+pub struct EdgeWeightsMut<'a, E: 'a, Ix: IndexType = DefaultIx> {
+ edges: ::std::slice::IterMut<'a, Edge<E, Ix>>,
+}
+
+impl<'a, E, Ix> Iterator for EdgeWeightsMut<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = &'a mut E;
+
+ fn next(&mut self) -> Option<&'a mut E> {
+ self.edges.next().map(|edge| &mut edge.weight)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.edges.size_hint()
+ }
+}
+
+/// Index the `Graph` by `NodeIndex` to access node weights.
+///
+/// **Panics** if the node doesn't exist.
+impl<N, E, Ty, Ix> Index<NodeIndex<Ix>> for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Output = N;
+ fn index(&self, index: NodeIndex<Ix>) -> &N {
+ &self.nodes[index.index()].weight
+ }
+}
+
+/// Index the `Graph` by `NodeIndex` to access node weights.
+///
+/// **Panics** if the node doesn't exist.
+impl<N, E, Ty, Ix> IndexMut<NodeIndex<Ix>> for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn index_mut(&mut self, index: NodeIndex<Ix>) -> &mut N {
+ &mut self.nodes[index.index()].weight
+ }
+}
+
+/// Index the `Graph` by `EdgeIndex` to access edge weights.
+///
+/// **Panics** if the edge doesn't exist.
+impl<N, E, Ty, Ix> Index<EdgeIndex<Ix>> for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Output = E;
+ fn index(&self, index: EdgeIndex<Ix>) -> &E {
+ &self.edges[index.index()].weight
+ }
+}
+
+/// Index the `Graph` by `EdgeIndex` to access edge weights.
+///
+/// **Panics** if the edge doesn't exist.
+impl<N, E, Ty, Ix> IndexMut<EdgeIndex<Ix>> for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn index_mut(&mut self, index: EdgeIndex<Ix>) -> &mut E {
+ &mut self.edges[index.index()].weight
+ }
+}
+
+/// Create a new empty `Graph`.
+impl<N, E, Ty, Ix> Default for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn default() -> Self {
+ Self::with_capacity(0, 0)
+ }
+}
+
+/// A `GraphIndex` is a node or edge index.
+pub trait GraphIndex: Copy {
+ #[doc(hidden)]
+ fn index(&self) -> usize;
+ #[doc(hidden)]
+ fn is_node_index() -> bool;
+}
+
+impl<Ix: IndexType> GraphIndex for NodeIndex<Ix> {
+ #[inline]
+ fn index(&self) -> usize {
+ NodeIndex::index(*self)
+ }
+ #[inline]
+ fn is_node_index() -> bool {
+ true
+ }
+}
+
+impl<Ix: IndexType> GraphIndex for EdgeIndex<Ix> {
+ #[inline]
+ fn index(&self) -> usize {
+ EdgeIndex::index(*self)
+ }
+ #[inline]
+ fn is_node_index() -> bool {
+ false
+ }
+}
+
+/// A “walker” object that can be used to step through the edge list of a node.
+///
+/// Created with [`.detach()`](struct.Neighbors.html#method.detach).
+///
+/// The walker does not borrow from the graph, so it lets you step through
+/// neighbors or incident edges while also mutating graph weights, as
+/// in the following example:
+///
+/// ```
+/// use petgraph::{Graph, Incoming};
+/// use petgraph::visit::Dfs;
+///
+/// let mut gr = Graph::new();
+/// let a = gr.add_node(0.);
+/// let b = gr.add_node(0.);
+/// let c = gr.add_node(0.);
+/// gr.add_edge(a, b, 3.);
+/// gr.add_edge(b, c, 2.);
+/// gr.add_edge(c, b, 1.);
+///
+/// // step through the graph and sum incoming edges into the node weight
+/// let mut dfs = Dfs::new(&gr, a);
+/// while let Some(node) = dfs.next(&gr) {
+/// // use a detached neighbors walker
+/// let mut edges = gr.neighbors_directed(node, Incoming).detach();
+/// while let Some(edge) = edges.next_edge(&gr) {
+/// gr[node] += gr[edge];
+/// }
+/// }
+///
+/// // check the result
+/// assert_eq!(gr[a], 0.);
+/// assert_eq!(gr[b], 4.);
+/// assert_eq!(gr[c], 2.);
+/// ```
+pub struct WalkNeighbors<Ix> {
+ skip_start: NodeIndex<Ix>,
+ next: [EdgeIndex<Ix>; 2],
+}
+
+impl<Ix> Clone for WalkNeighbors<Ix>
+where
+ Ix: IndexType,
+{
+ fn clone(&self) -> Self {
+ WalkNeighbors {
+ skip_start: self.skip_start,
+ next: self.next,
+ }
+ }
+}
+
+impl<Ix: IndexType> WalkNeighbors<Ix> {
+ /// Step to the next edge and its endpoint node in the walk for graph `g`.
+ ///
+ /// The next node indices are always the others than the starting point
+ /// where the `WalkNeighbors` value was created.
+ /// For an `Outgoing` walk, the target nodes,
+ /// for an `Incoming` walk, the source nodes of the edge.
+ pub fn next<N, E, Ty: EdgeType>(
+ &mut self,
+ g: &Graph<N, E, Ty, Ix>,
+ ) -> Option<(EdgeIndex<Ix>, NodeIndex<Ix>)> {
+ // First any outgoing edges
+ match g.edges.get(self.next[0].index()) {
+ None => {}
+ Some(edge) => {
+ let ed = self.next[0];
+ self.next[0] = edge.next[0];
+ return Some((ed, edge.node[1]));
+ }
+ }
+ // Then incoming edges
+ // For an "undirected" iterator (traverse both incoming
+ // and outgoing edge lists), make sure we don't double
+ // count selfloops by skipping them in the incoming list.
+ while let Some(edge) = g.edges.get(self.next[1].index()) {
+ let ed = self.next[1];
+ self.next[1] = edge.next[1];
+ if edge.node[0] != self.skip_start {
+ return Some((ed, edge.node[0]));
+ }
+ }
+ None
+ }
+
+ pub fn next_node<N, E, Ty: EdgeType>(
+ &mut self,
+ g: &Graph<N, E, Ty, Ix>,
+ ) -> Option<NodeIndex<Ix>> {
+ self.next(g).map(|t| t.1)
+ }
+
+ pub fn next_edge<N, E, Ty: EdgeType>(
+ &mut self,
+ g: &Graph<N, E, Ty, Ix>,
+ ) -> Option<EdgeIndex<Ix>> {
+ self.next(g).map(|t| t.0)
+ }
+}
+
+/// Iterator over the node indices of a graph.
+#[derive(Clone, Debug)]
+pub struct NodeIndices<Ix = DefaultIx> {
+ r: Range<usize>,
+ ty: PhantomData<fn() -> Ix>,
+}
+
+impl<Ix: IndexType> Iterator for NodeIndices<Ix> {
+ type Item = NodeIndex<Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.r.next().map(node_index)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.r.size_hint()
+ }
+}
+
+impl<Ix: IndexType> DoubleEndedIterator for NodeIndices<Ix> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.r.next_back().map(node_index)
+ }
+}
+
+impl<Ix: IndexType> ExactSizeIterator for NodeIndices<Ix> {}
+
+/// Iterator over the edge indices of a graph.
+#[derive(Clone, Debug)]
+pub struct EdgeIndices<Ix = DefaultIx> {
+ r: Range<usize>,
+ ty: PhantomData<fn() -> Ix>,
+}
+
+impl<Ix: IndexType> Iterator for EdgeIndices<Ix> {
+ type Item = EdgeIndex<Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.r.next().map(edge_index)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.r.size_hint()
+ }
+}
+
+impl<Ix: IndexType> DoubleEndedIterator for EdgeIndices<Ix> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.r.next_back().map(edge_index)
+ }
+}
+
+impl<Ix: IndexType> ExactSizeIterator for EdgeIndices<Ix> {}
+
+/// Reference to a `Graph` edge.
+#[derive(Debug)]
+pub struct EdgeReference<'a, E: 'a, Ix = DefaultIx> {
+ index: EdgeIndex<Ix>,
+ node: [NodeIndex<Ix>; 2],
+ weight: &'a E,
+}
+
+impl<'a, E, Ix: IndexType> Clone for EdgeReference<'a, E, Ix> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<'a, E, Ix: IndexType> Copy for EdgeReference<'a, E, Ix> {}
+
+impl<'a, E, Ix: IndexType> PartialEq for EdgeReference<'a, E, Ix>
+where
+ E: PartialEq,
+{
+ fn eq(&self, rhs: &Self) -> bool {
+ self.index == rhs.index && self.weight == rhs.weight
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoNodeReferences for &'a Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeRef = (NodeIndex<Ix>, &'a N);
+ type NodeReferences = NodeReferences<'a, N, Ix>;
+ fn node_references(self) -> Self::NodeReferences {
+ NodeReferences {
+ iter: self.nodes.iter().enumerate(),
+ }
+ }
+}
+
+/// Iterator over all nodes of a graph.
+pub struct NodeReferences<'a, N: 'a, Ix: IndexType = DefaultIx> {
+ iter: iter::Enumerate<slice::Iter<'a, Node<N, Ix>>>,
+}
+
+impl<'a, N, Ix> Iterator for NodeReferences<'a, N, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = (NodeIndex<Ix>, &'a N);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter
+ .next()
+ .map(|(i, node)| (node_index(i), &node.weight))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, N, Ix> DoubleEndedIterator for NodeReferences<'a, N, Ix>
+where
+ Ix: IndexType,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter
+ .next_back()
+ .map(|(i, node)| (node_index(i), &node.weight))
+ }
+}
+
+impl<'a, N, Ix> ExactSizeIterator for NodeReferences<'a, N, Ix> where Ix: IndexType {}
+
+impl<'a, Ix, E> EdgeReference<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ /// Access the edge’s weight.
+ ///
+ /// **NOTE** that this method offers a longer lifetime
+ /// than the trait (unfortunately they don't match yet).
+ pub fn weight(&self) -> &'a E {
+ self.weight
+ }
+}
+
+impl<'a, Ix, E> EdgeRef for EdgeReference<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ type NodeId = NodeIndex<Ix>;
+ type EdgeId = EdgeIndex<Ix>;
+ type Weight = E;
+
+ fn source(&self) -> Self::NodeId {
+ self.node[0]
+ }
+ fn target(&self) -> Self::NodeId {
+ self.node[1]
+ }
+ fn weight(&self) -> &E {
+ self.weight
+ }
+ fn id(&self) -> Self::EdgeId {
+ self.index
+ }
+}
+
+/// Iterator over all edges of a graph.
+pub struct EdgeReferences<'a, E: 'a, Ix: IndexType = DefaultIx> {
+ iter: iter::Enumerate<slice::Iter<'a, Edge<E, Ix>>>,
+}
+
+impl<'a, E, Ix> Iterator for EdgeReferences<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = EdgeReference<'a, E, Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(|(i, edge)| EdgeReference {
+ index: edge_index(i),
+ node: edge.node,
+ weight: &edge.weight,
+ })
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, E, Ix> DoubleEndedIterator for EdgeReferences<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.next_back().map(|(i, edge)| EdgeReference {
+ index: edge_index(i),
+ node: edge.node,
+ weight: &edge.weight,
+ })
+ }
+}
+
+impl<'a, E, Ix> ExactSizeIterator for EdgeReferences<'a, E, Ix> where Ix: IndexType {}
+
+mod frozen;
+#[cfg(feature = "stable_graph")]
+pub mod stable_graph;
+
+/// `Frozen` is a graph wrapper.
+///
+/// The `Frozen` only allows shared access (read-only) to the
+/// underlying graph `G`, but it allows mutable access to its
+/// node and edge weights.
+///
+/// This is used to ensure immutability of the graph's structure
+/// while permitting weights to be both read and written.
+///
+/// See indexing implementations and the traits `Data` and `DataMap`
+/// for read-write access to the graph's weights.
+pub struct Frozen<'a, G: 'a>(&'a mut G);
diff --git a/vendor/petgraph/src/graph_impl/serialization.rs b/vendor/petgraph/src/graph_impl/serialization.rs
new file mode 100644
index 000000000..e108f3dd4
--- /dev/null
+++ b/vendor/petgraph/src/graph_impl/serialization.rs
@@ -0,0 +1,345 @@
+use serde::de::Error;
+
+use std::marker::PhantomData;
+
+use crate::prelude::*;
+
+use crate::graph::Node;
+use crate::graph::{Edge, IndexType};
+use crate::serde_utils::CollectSeqWithLength;
+use crate::serde_utils::MappedSequenceVisitor;
+use crate::serde_utils::{FromDeserialized, IntoSerializable};
+use crate::EdgeType;
+
+use super::{EdgeIndex, NodeIndex};
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+/// Serialization representation for Graph
+/// Keep in sync with deserialization and StableGraph
+///
+/// The serialization format is as follows, in Pseudorust:
+///
+/// Graph {
+/// nodes: [N],
+/// node_holes: [NodeIndex<Ix>],
+/// edge_property: EdgeProperty,
+/// edges: [Option<(NodeIndex<Ix>, NodeIndex<Ix>, E)>]
+/// }
+///
+/// The same format is used by both Graph and StableGraph.
+///
+/// For graph there are restrictions:
+/// node_holes is always empty and edges are always Some
+///
+/// A stable graph serialization that obeys these restrictions
+/// (effectively, it has no interior vacancies) can de deserialized
+/// as a graph.
+///
+/// Node indices are serialized as integers and are fixed size for
+/// binary formats, so the Ix parameter matters there.
+#[derive(Serialize)]
+#[serde(rename = "Graph")]
+#[serde(bound(serialize = "N: Serialize, E: Serialize, Ix: IndexType + Serialize"))]
+pub struct SerGraph<'a, N: 'a, E: 'a, Ix: 'a + IndexType> {
+ #[serde(serialize_with = "ser_graph_nodes")]
+ nodes: &'a [Node<N, Ix>],
+ node_holes: &'a [NodeIndex<Ix>],
+ edge_property: EdgeProperty,
+ #[serde(serialize_with = "ser_graph_edges")]
+ edges: &'a [Edge<E, Ix>],
+}
+
+// Deserialization representation for Graph
+// Keep in sync with serialization and StableGraph
+#[derive(Deserialize)]
+#[serde(rename = "Graph")]
+#[serde(bound(
+ deserialize = "N: Deserialize<'de>, E: Deserialize<'de>, Ix: IndexType + Deserialize<'de>"
+))]
+pub struct DeserGraph<N, E, Ix> {
+ #[serde(deserialize_with = "deser_graph_nodes")]
+ nodes: Vec<Node<N, Ix>>,
+ #[serde(deserialize_with = "deser_graph_node_holes")]
+ #[allow(unused)]
+ #[serde(default = "Vec::new")]
+ node_holes: Vec<NodeIndex<Ix>>,
+ edge_property: EdgeProperty,
+ #[serde(deserialize_with = "deser_graph_edges")]
+ edges: Vec<Edge<E, Ix>>,
+}
+
+impl<Ix> Serialize for NodeIndex<Ix>
+where
+ Ix: IndexType + Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.serialize(serializer)
+ }
+}
+
+impl<'de, Ix> Deserialize<'de> for NodeIndex<Ix>
+where
+ Ix: IndexType + Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(NodeIndex(Ix::deserialize(deserializer)?))
+ }
+}
+
+impl<Ix> Serialize for EdgeIndex<Ix>
+where
+ Ix: IndexType + Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.serialize(serializer)
+ }
+}
+
+impl<'de, Ix> Deserialize<'de> for EdgeIndex<Ix>
+where
+ Ix: IndexType + Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(EdgeIndex(Ix::deserialize(deserializer)?))
+ }
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+#[derive(Debug)]
+pub enum EdgeProperty {
+ Undirected,
+ Directed,
+}
+
+impl EdgeProperty {
+ pub fn is_directed(&self) -> bool {
+ match *self {
+ EdgeProperty::Directed => true,
+ EdgeProperty::Undirected => false,
+ }
+ }
+}
+
+impl<Ty> From<PhantomData<Ty>> for EdgeProperty
+where
+ Ty: EdgeType,
+{
+ fn from(_: PhantomData<Ty>) -> Self {
+ if Ty::is_directed() {
+ EdgeProperty::Directed
+ } else {
+ EdgeProperty::Undirected
+ }
+ }
+}
+
+impl<Ty> FromDeserialized for PhantomData<Ty>
+where
+ Ty: EdgeType,
+{
+ type Input = EdgeProperty;
+ fn from_deserialized<E2>(input: Self::Input) -> Result<Self, E2>
+ where
+ E2: Error,
+ {
+ if input.is_directed() != Ty::is_directed() {
+ Err(E2::custom(format_args!(
+ "graph edge property mismatch, \
+ expected {:?}, found {:?}",
+ EdgeProperty::from(PhantomData::<Ty>),
+ input
+ )))
+ } else {
+ Ok(PhantomData)
+ }
+ }
+}
+
+fn ser_graph_nodes<S, N, Ix>(nodes: &&[Node<N, Ix>], serializer: S) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+ N: Serialize,
+ Ix: Serialize + IndexType,
+{
+ serializer.collect_seq_exact(nodes.iter().map(|node| &node.weight))
+}
+
+fn ser_graph_edges<S, E, Ix>(edges: &&[Edge<E, Ix>], serializer: S) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+ E: Serialize,
+ Ix: Serialize + IndexType,
+{
+ serializer.collect_seq_exact(
+ edges
+ .iter()
+ .map(|edge| Some((edge.source(), edge.target(), &edge.weight))),
+ )
+}
+
+fn deser_graph_nodes<'de, D, N, Ix>(deserializer: D) -> Result<Vec<Node<N, Ix>>, D::Error>
+where
+ D: Deserializer<'de>,
+ N: Deserialize<'de>,
+ Ix: IndexType + Deserialize<'de>,
+{
+ deserializer.deserialize_seq(MappedSequenceVisitor::new(|n| {
+ Ok(Node {
+ weight: n,
+ next: [EdgeIndex::end(); 2],
+ })
+ }))
+}
+
+fn deser_graph_node_holes<'de, D, Ix>(deserializer: D) -> Result<Vec<NodeIndex<Ix>>, D::Error>
+where
+ D: Deserializer<'de>,
+ Ix: IndexType + Deserialize<'de>,
+{
+ deserializer.deserialize_seq(
+ MappedSequenceVisitor::<NodeIndex<Ix>, NodeIndex<Ix>, _>::new(|_| {
+ Err("Graph can not have holes in the node set, found non-empty node_holes")
+ }),
+ )
+}
+
+fn deser_graph_edges<'de, D, N, Ix>(deserializer: D) -> Result<Vec<Edge<N, Ix>>, D::Error>
+where
+ D: Deserializer<'de>,
+ N: Deserialize<'de>,
+ Ix: IndexType + Deserialize<'de>,
+{
+ deserializer.deserialize_seq(MappedSequenceVisitor::<
+ Option<(NodeIndex<Ix>, NodeIndex<Ix>, N)>,
+ _,
+ _,
+ >::new(|x| {
+ if let Some((i, j, w)) = x {
+ Ok(Edge {
+ weight: w,
+ node: [i, j],
+ next: [EdgeIndex::end(); 2],
+ })
+ } else {
+ Err("Graph can not have holes in the edge set, found None, expected edge")
+ }
+ }))
+}
+
+impl<'a, N, E, Ty, Ix> IntoSerializable for &'a Graph<N, E, Ty, Ix>
+where
+ Ix: IndexType,
+ Ty: EdgeType,
+{
+ type Output = SerGraph<'a, N, E, Ix>;
+ fn into_serializable(self) -> Self::Output {
+ SerGraph {
+ nodes: &self.nodes,
+ node_holes: &[],
+ edges: &self.edges,
+ edge_property: EdgeProperty::from(PhantomData::<Ty>),
+ }
+ }
+}
+
+/// Requires crate feature `"serde-1"`
+impl<N, E, Ty, Ix> Serialize for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType + Serialize,
+ N: Serialize,
+ E: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.into_serializable().serialize(serializer)
+ }
+}
+
+pub fn invalid_node_err<E>(node_index: usize, len: usize) -> E
+where
+ E: Error,
+{
+ E::custom(format_args!(
+ "invalid value: node index `{}` does not exist in graph \
+ with node bound {}",
+ node_index, len
+ ))
+}
+
+pub fn invalid_length_err<Ix, E>(node_or_edge: &str, len: usize) -> E
+where
+ E: Error,
+ Ix: IndexType,
+{
+ E::custom(format_args!(
+ "invalid size: graph {} count {} exceeds index type maximum {}",
+ node_or_edge,
+ len,
+ <Ix as IndexType>::max().index()
+ ))
+}
+
+impl<'a, N, E, Ty, Ix> FromDeserialized for Graph<N, E, Ty, Ix>
+where
+ Ix: IndexType,
+ Ty: EdgeType,
+{
+ type Input = DeserGraph<N, E, Ix>;
+ fn from_deserialized<E2>(input: Self::Input) -> Result<Self, E2>
+ where
+ E2: Error,
+ {
+ let ty = PhantomData::<Ty>::from_deserialized(input.edge_property)?;
+ let nodes = input.nodes;
+ let edges = input.edges;
+ if nodes.len() >= <Ix as IndexType>::max().index() {
+ Err(invalid_length_err::<Ix, _>("node", nodes.len()))?
+ }
+
+ if edges.len() >= <Ix as IndexType>::max().index() {
+ Err(invalid_length_err::<Ix, _>("edge", edges.len()))?
+ }
+
+ let mut gr = Graph {
+ nodes: nodes,
+ edges: edges,
+ ty: ty,
+ };
+ let nc = gr.node_count();
+ gr.link_edges()
+ .map_err(|i| invalid_node_err(i.index(), nc))?;
+ Ok(gr)
+ }
+}
+
+/// Requires crate feature `"serde-1"`
+impl<'de, N, E, Ty, Ix> Deserialize<'de> for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType + Deserialize<'de>,
+ N: Deserialize<'de>,
+ E: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Self::from_deserialized(DeserGraph::deserialize(deserializer)?)
+ }
+}
diff --git a/vendor/petgraph/src/graph_impl/stable_graph/mod.rs b/vendor/petgraph/src/graph_impl/stable_graph/mod.rs
new file mode 100644
index 000000000..142aaebed
--- /dev/null
+++ b/vendor/petgraph/src/graph_impl/stable_graph/mod.rs
@@ -0,0 +1,1817 @@
+//! `StableGraph` keeps indices stable across removals.
+//!
+//! Depends on `feature = "stable_graph"`.
+//!
+
+use std::cmp;
+use std::fmt;
+use std::iter;
+use std::marker::PhantomData;
+use std::mem::replace;
+use std::mem::size_of;
+use std::ops::{Index, IndexMut};
+use std::slice;
+
+use crate::{Directed, Direction, EdgeType, Graph, Incoming, Outgoing, Undirected};
+
+use crate::iter_format::{DebugMap, IterFormatExt, NoPretty};
+use crate::iter_utils::IterUtilsExt;
+
+use super::{index_twice, Edge, Frozen, Node, Pair, DIRECTIONS};
+use crate::visit::{
+ EdgeRef, IntoEdgeReferences, IntoEdges, IntoEdgesDirected, IntoNodeReferences, NodeIndexable,
+};
+use crate::IntoWeightedEdge;
+
+// reexport those things that are shared with Graph
+#[doc(no_inline)]
+pub use crate::graph::{
+ edge_index, node_index, DefaultIx, EdgeIndex, GraphIndex, IndexType, NodeIndex,
+};
+
+use crate::util::enumerate;
+
+#[cfg(feature = "serde-1")]
+mod serialization;
+
+/// `StableGraph<N, E, Ty, Ix>` is a graph datastructure using an adjacency
+/// list representation.
+///
+/// The graph **does not invalidate** any unrelated node or edge indices when
+/// items are removed.
+///
+/// `StableGraph` is parameterized over:
+///
+/// - Associated data `N` for nodes and `E` for edges, also called *weights*.
+/// The associated data can be of arbitrary type.
+/// - Edge type `Ty` that determines whether the graph edges are directed or undirected.
+/// - Index type `Ix`, which determines the maximum size of the graph.
+///
+/// The graph uses **O(|V| + |E|)** space, and allows fast node and edge insert
+/// and efficient graph search.
+///
+/// It implements **O(e')** edge lookup and edge and node removals, where **e'**
+/// is some local measure of edge count.
+///
+/// - Nodes and edges are each numbered in an interval from *0* to some number
+/// *m*, but *not all* indices in the range are valid, since gaps are formed
+/// by deletions.
+///
+/// - You can select graph index integer type after the size of the graph. A smaller
+/// size may have better performance.
+///
+/// - Using indices allows mutation while traversing the graph, see `Dfs`.
+///
+/// - The `StableGraph` is a regular rust collection and is `Send` and `Sync`
+/// (as long as associated data `N` and `E` are).
+///
+/// - Indices don't allow as much compile time checking as references.
+///
+/// Depends on crate feature `stable_graph` (default). *Stable Graph is still
+/// missing a few methods compared to Graph. You can contribute to help it
+/// achieve parity.*
+pub struct StableGraph<N, E, Ty = Directed, Ix = DefaultIx> {
+ g: Graph<Option<N>, Option<E>, Ty, Ix>,
+ node_count: usize,
+ edge_count: usize,
+
+ // node and edge free lists (both work the same way)
+ //
+ // free_node, if not NodeIndex::end(), points to a node index
+ // that is vacant (after a deletion). The next item in the list is kept in
+ // that Node's Node.next[0] field. For Node, it's a node index stored
+ // in an EdgeIndex location, and the _into_edge()/_into_node() methods
+ // convert.
+ free_node: NodeIndex<Ix>,
+ free_edge: EdgeIndex<Ix>,
+}
+
+/// A `StableGraph` with directed edges.
+///
+/// For example, an edge from *1* to *2* is distinct from an edge from *2* to
+/// *1*.
+pub type StableDiGraph<N, E, Ix = DefaultIx> = StableGraph<N, E, Directed, Ix>;
+
+/// A `StableGraph` with undirected edges.
+///
+/// For example, an edge between *1* and *2* is equivalent to an edge between
+/// *2* and *1*.
+pub type StableUnGraph<N, E, Ix = DefaultIx> = StableGraph<N, E, Undirected, Ix>;
+
+impl<N, E, Ty, Ix> fmt::Debug for StableGraph<N, E, Ty, Ix>
+where
+ N: fmt::Debug,
+ E: fmt::Debug,
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let etype = if self.is_directed() {
+ "Directed"
+ } else {
+ "Undirected"
+ };
+ let mut fmt_struct = f.debug_struct("StableGraph");
+ fmt_struct.field("Ty", &etype);
+ fmt_struct.field("node_count", &self.node_count);
+ fmt_struct.field("edge_count", &self.edge_count);
+ if self.g.edges.iter().any(|e| e.weight.is_some()) {
+ fmt_struct.field(
+ "edges",
+ &self
+ .g
+ .edges
+ .iter()
+ .filter(|e| e.weight.is_some())
+ .map(|e| NoPretty((e.source().index(), e.target().index())))
+ .format(", "),
+ );
+ }
+ // skip weights if they are ZST!
+ if size_of::<N>() != 0 {
+ fmt_struct.field(
+ "node weights",
+ &DebugMap(|| {
+ self.g
+ .nodes
+ .iter()
+ .map(|n| n.weight.as_ref())
+ .enumerate()
+ .filter_map(|(i, wo)| wo.map(move |w| (i, w)))
+ }),
+ );
+ }
+ if size_of::<E>() != 0 {
+ fmt_struct.field(
+ "edge weights",
+ &DebugMap(|| {
+ self.g
+ .edges
+ .iter()
+ .map(|n| n.weight.as_ref())
+ .enumerate()
+ .filter_map(|(i, wo)| wo.map(move |w| (i, w)))
+ }),
+ );
+ }
+ fmt_struct.field("free_node", &self.free_node);
+ fmt_struct.field("free_edge", &self.free_edge);
+ fmt_struct.finish()
+ }
+}
+
+impl<N, E> StableGraph<N, E, Directed> {
+ /// Create a new `StableGraph` with directed edges.
+ ///
+ /// This is a convenience method. See `StableGraph::with_capacity`
+ /// or `StableGraph::default` for a constructor that is generic in all the
+ /// type parameters of `StableGraph`.
+ pub fn new() -> Self {
+ Self::with_capacity(0, 0)
+ }
+}
+
+impl<N, E, Ty, Ix> StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ /// Create a new `StableGraph` with estimated capacity.
+ pub fn with_capacity(nodes: usize, edges: usize) -> Self {
+ StableGraph {
+ g: Graph::with_capacity(nodes, edges),
+ node_count: 0,
+ edge_count: 0,
+ free_node: NodeIndex::end(),
+ free_edge: EdgeIndex::end(),
+ }
+ }
+
+ /// Return the current node and edge capacity of the graph.
+ pub fn capacity(&self) -> (usize, usize) {
+ self.g.capacity()
+ }
+
+ /// Remove all nodes and edges
+ pub fn clear(&mut self) {
+ self.node_count = 0;
+ self.edge_count = 0;
+ self.free_node = NodeIndex::end();
+ self.free_edge = EdgeIndex::end();
+ self.g.clear();
+ }
+
+ /// Remove all edges
+ pub fn clear_edges(&mut self) {
+ self.edge_count = 0;
+ self.free_edge = EdgeIndex::end();
+ self.g.edges.clear();
+ // clear edges without touching the free list
+ for node in &mut self.g.nodes {
+ if node.weight.is_some() {
+ node.next = [EdgeIndex::end(), EdgeIndex::end()];
+ }
+ }
+ }
+
+ /// Return the number of nodes (vertices) in the graph.
+ ///
+ /// Computes in **O(1)** time.
+ pub fn node_count(&self) -> usize {
+ self.node_count
+ }
+
+ /// Return the number of edges in the graph.
+ ///
+ /// Computes in **O(1)** time.
+ pub fn edge_count(&self) -> usize {
+ self.edge_count
+ }
+
+ /// Whether the graph has directed edges or not.
+ #[inline]
+ pub fn is_directed(&self) -> bool {
+ Ty::is_directed()
+ }
+
+ /// Add a node (also called vertex) with associated data `weight` to the graph.
+ ///
+ /// Computes in **O(1)** time.
+ ///
+ /// Return the index of the new node.
+ ///
+ /// **Panics** if the `StableGraph` is at the maximum number of nodes for
+ /// its index type.
+ pub fn add_node(&mut self, weight: N) -> NodeIndex<Ix> {
+ let index = if self.free_node != NodeIndex::end() {
+ let node_idx = self.free_node;
+ let node_slot = &mut self.g.nodes[node_idx.index()];
+ let _old = replace(&mut node_slot.weight, Some(weight));
+ debug_assert!(_old.is_none());
+ self.free_node = node_slot.next[0]._into_node();
+ node_slot.next[0] = EdgeIndex::end();
+ node_idx
+ } else {
+ self.g.add_node(Some(weight))
+ };
+ self.node_count += 1;
+ index
+ }
+
+ /// free_node: Which free list to update for the vacancy
+ fn add_vacant_node(&mut self, free_node: &mut NodeIndex<Ix>) {
+ let node_idx = self.g.add_node(None);
+ // link the free list
+ let node_slot = &mut self.g.nodes[node_idx.index()];
+ node_slot.next[0] = free_node._into_edge();
+ *free_node = node_idx;
+ }
+
+ /// Remove `a` from the graph if it exists, and return its weight.
+ /// If it doesn't exist in the graph, return `None`.
+ ///
+ /// The node index `a` is invalidated, but none other.
+ /// Edge indices are invalidated as they would be following the removal of
+ /// each edge with an endpoint in `a`.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of affected
+ /// edges, including *n* calls to `.remove_edge()` where *n* is the number
+ /// of edges with an endpoint in `a`.
+ pub fn remove_node(&mut self, a: NodeIndex<Ix>) -> Option<N> {
+ let node_weight = self.g.nodes.get_mut(a.index())?.weight.take()?;
+ for d in &DIRECTIONS {
+ let k = d.index();
+
+ // Remove all edges from and to this node.
+ loop {
+ let next = self.g.nodes[a.index()].next[k];
+ if next == EdgeIndex::end() {
+ break;
+ }
+ let ret = self.remove_edge(next);
+ debug_assert!(ret.is_some());
+ let _ = ret;
+ }
+ }
+
+ let node_slot = &mut self.g.nodes[a.index()];
+ //let node_weight = replace(&mut self.g.nodes[a.index()].weight, Entry::Empty(self.free_node));
+ //self.g.nodes[a.index()].next = [EdgeIndex::end(), EdgeIndex::end()];
+ node_slot.next = [self.free_node._into_edge(), EdgeIndex::end()];
+ self.free_node = a;
+ self.node_count -= 1;
+
+ Some(node_weight)
+ }
+
+ pub fn contains_node(&self, a: NodeIndex<Ix>) -> bool {
+ self.get_node(a).is_some()
+ }
+
+ // Return the Node if it is not vacant (non-None weight)
+ fn get_node(&self, a: NodeIndex<Ix>) -> Option<&Node<Option<N>, Ix>> {
+ self.g
+ .nodes
+ .get(a.index())
+ .and_then(|node| node.weight.as_ref().map(move |_| node))
+ }
+
+ /// Add an edge from `a` to `b` to the graph, with its associated
+ /// data `weight`.
+ ///
+ /// Return the index of the new edge.
+ ///
+ /// Computes in **O(1)** time.
+ ///
+ /// **Panics** if any of the nodes don't exist.<br>
+ /// **Panics** if the `StableGraph` is at the maximum number of edges for
+ /// its index type.
+ ///
+ /// **Note:** `StableGraph` allows adding parallel (“duplicate”) edges.
+ pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
+ let edge_idx;
+ let mut new_edge = None::<Edge<_, _>>;
+ {
+ let edge: &mut Edge<_, _>;
+
+ if self.free_edge != EdgeIndex::end() {
+ edge_idx = self.free_edge;
+ edge = &mut self.g.edges[edge_idx.index()];
+ let _old = replace(&mut edge.weight, Some(weight));
+ debug_assert!(_old.is_none());
+ self.free_edge = edge.next[0];
+ edge.node = [a, b];
+ } else {
+ edge_idx = EdgeIndex::new(self.g.edges.len());
+ assert!(<Ix as IndexType>::max().index() == !0 || EdgeIndex::end() != edge_idx);
+ new_edge = Some(Edge {
+ weight: Some(weight),
+ node: [a, b],
+ next: [EdgeIndex::end(); 2],
+ });
+ edge = new_edge.as_mut().unwrap();
+ }
+
+ let wrong_index = match index_twice(&mut self.g.nodes, a.index(), b.index()) {
+ Pair::None => Some(cmp::max(a.index(), b.index())),
+ Pair::One(an) => {
+ if an.weight.is_none() {
+ Some(a.index())
+ } else {
+ edge.next = an.next;
+ an.next[0] = edge_idx;
+ an.next[1] = edge_idx;
+ None
+ }
+ }
+ Pair::Both(an, bn) => {
+ // a and b are different indices
+ if an.weight.is_none() {
+ Some(a.index())
+ } else if bn.weight.is_none() {
+ Some(b.index())
+ } else {
+ edge.next = [an.next[0], bn.next[1]];
+ an.next[0] = edge_idx;
+ bn.next[1] = edge_idx;
+ None
+ }
+ }
+ };
+ if let Some(i) = wrong_index {
+ panic!(
+ "StableGraph::add_edge: node index {} is not a node in the graph",
+ i
+ );
+ }
+ self.edge_count += 1;
+ }
+ if let Some(edge) = new_edge {
+ self.g.edges.push(edge);
+ }
+ edge_idx
+ }
+
+ /// free_edge: Which free list to update for the vacancy
+ fn add_vacant_edge(&mut self, free_edge: &mut EdgeIndex<Ix>) {
+ let edge_idx = EdgeIndex::new(self.g.edges.len());
+ debug_assert!(edge_idx != EdgeIndex::end());
+ let mut edge = Edge {
+ weight: None,
+ node: [NodeIndex::end(); 2],
+ next: [EdgeIndex::end(); 2],
+ };
+ edge.next[0] = *free_edge;
+ *free_edge = edge_idx;
+ self.g.edges.push(edge);
+ }
+
+ /// Add or update an edge from `a` to `b`.
+ /// If the edge already exists, its weight is updated.
+ ///
+ /// Return the index of the affected edge.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of edges
+ /// connected to `a` (and `b`, if the graph edges are undirected).
+ ///
+ /// **Panics** if any of the nodes don't exist.
+ pub fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
+ if let Some(ix) = self.find_edge(a, b) {
+ self[ix] = weight;
+ return ix;
+ }
+ self.add_edge(a, b, weight)
+ }
+
+ /// Remove an edge and return its edge weight, or `None` if it didn't exist.
+ ///
+ /// Invalidates the edge index `e` but no other.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of edges
+ /// connected to the same endpoints as `e`.
+ pub fn remove_edge(&mut self, e: EdgeIndex<Ix>) -> Option<E> {
+ // every edge is part of two lists,
+ // outgoing and incoming edges.
+ // Remove it from both
+ let (is_edge, edge_node, edge_next) = match self.g.edges.get(e.index()) {
+ None => return None,
+ Some(x) => (x.weight.is_some(), x.node, x.next),
+ };
+ if !is_edge {
+ return None;
+ }
+
+ // Remove the edge from its in and out lists by replacing it with
+ // a link to the next in the list.
+ self.g.change_edge_links(edge_node, e, edge_next);
+
+ // Clear the edge and put it in the free list
+ let edge = &mut self.g.edges[e.index()];
+ edge.next = [self.free_edge, EdgeIndex::end()];
+ edge.node = [NodeIndex::end(), NodeIndex::end()];
+ self.free_edge = e;
+ self.edge_count -= 1;
+ edge.weight.take()
+ }
+
+ /// Access the weight for node `a`.
+ ///
+ /// Also available with indexing syntax: `&graph[a]`.
+ pub fn node_weight(&self, a: NodeIndex<Ix>) -> Option<&N> {
+ match self.g.nodes.get(a.index()) {
+ Some(no) => no.weight.as_ref(),
+ None => None,
+ }
+ }
+
+ /// Access the weight for node `a`, mutably.
+ ///
+ /// Also available with indexing syntax: `&mut graph[a]`.
+ pub fn node_weight_mut(&mut self, a: NodeIndex<Ix>) -> Option<&mut N> {
+ match self.g.nodes.get_mut(a.index()) {
+ Some(no) => no.weight.as_mut(),
+ None => None,
+ }
+ }
+
+ /// Return an iterator yielding mutable access to all node weights.
+ ///
+ /// The order in which weights are yielded matches the order of their node
+ /// indices.
+ pub fn node_weights_mut(&mut self) -> impl Iterator<Item = &mut N> {
+ self.g
+ .node_weights_mut()
+ .flat_map(|maybe_node| maybe_node.iter_mut())
+ }
+
+ /// Return an iterator over the node indices of the graph
+ pub fn node_indices(&self) -> NodeIndices<N, Ix> {
+ NodeIndices {
+ iter: enumerate(self.raw_nodes()),
+ }
+ }
+
+ /// Access the weight for edge `e`.
+ ///
+ /// Also available with indexing syntax: `&graph[e]`.
+ pub fn edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E> {
+ match self.g.edges.get(e.index()) {
+ Some(ed) => ed.weight.as_ref(),
+ None => None,
+ }
+ }
+
+ /// Access the weight for edge `e`, mutably
+ ///
+ /// Also available with indexing syntax: `&mut graph[e]`.
+ pub fn edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E> {
+ match self.g.edges.get_mut(e.index()) {
+ Some(ed) => ed.weight.as_mut(),
+ None => None,
+ }
+ }
+
+ /// Return an iterator yielding mutable access to all edge weights.
+ ///
+ /// The order in which weights are yielded matches the order of their edge
+ /// indices.
+ pub fn edge_weights_mut(&mut self) -> impl Iterator<Item = &mut E> {
+ self.g
+ .edge_weights_mut()
+ .flat_map(|maybe_edge| maybe_edge.iter_mut())
+ }
+
+ /// Access the source and target nodes for `e`.
+ pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
+ match self.g.edges.get(e.index()) {
+ Some(ed) if ed.weight.is_some() => Some((ed.source(), ed.target())),
+ _otherwise => None,
+ }
+ }
+
+ /// Return an iterator over the edge indices of the graph
+ pub fn edge_indices(&self) -> EdgeIndices<E, Ix> {
+ EdgeIndices {
+ iter: enumerate(self.raw_edges()),
+ }
+ }
+
+ /// Lookup if there is an edge from `a` to `b`.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of edges
+ /// connected to `a` (and `b`, if the graph edges are undirected).
+ pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
+ self.find_edge(a, b).is_some()
+ }
+
+ /// Lookup an edge from `a` to `b`.
+ ///
+ /// Computes in **O(e')** time, where **e'** is the number of edges
+ /// connected to `a` (and `b`, if the graph edges are undirected).
+ pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
+ if !self.is_directed() {
+ self.find_edge_undirected(a, b).map(|(ix, _)| ix)
+ } else {
+ match self.get_node(a) {
+ None => None,
+ Some(node) => self.g.find_edge_directed_from_node(node, b),
+ }
+ }
+ }
+
+ /// Lookup an edge between `a` and `b`, in either direction.
+ ///
+ /// If the graph is undirected, then this is equivalent to `.find_edge()`.
+ ///
+ /// Return the edge index and its directionality, with `Outgoing` meaning
+ /// from `a` to `b` and `Incoming` the reverse,
+ /// or `None` if the edge does not exist.
+ pub fn find_edge_undirected(
+ &self,
+ a: NodeIndex<Ix>,
+ b: NodeIndex<Ix>,
+ ) -> Option<(EdgeIndex<Ix>, Direction)> {
+ match self.get_node(a) {
+ None => None,
+ Some(node) => self.g.find_edge_undirected_from_node(node, b),
+ }
+ }
+
+ /// Return an iterator of all nodes with an edge starting from `a`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges connected to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `NodeIndex<Ix>`.
+ ///
+ /// Use [`.neighbors(a).detach()`][1] to get a neighbor walker that does
+ /// not borrow from the graph.
+ ///
+ /// [1]: struct.Neighbors.html#method.detach
+ pub fn neighbors(&self, a: NodeIndex<Ix>) -> Neighbors<E, Ix> {
+ self.neighbors_directed(a, Outgoing)
+ }
+
+ /// Return an iterator of all neighbors that have an edge between them and `a`,
+ /// in the specified direction.
+ /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*.
+ ///
+ /// - `Directed`, `Outgoing`: All edges from `a`.
+ /// - `Directed`, `Incoming`: All edges to `a`.
+ /// - `Undirected`: All edges connected to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `NodeIndex<Ix>`.
+ ///
+ /// Use [`.neighbors_directed(a, dir).detach()`][1] to get a neighbor walker that does
+ /// not borrow from the graph.
+ ///
+ /// [1]: struct.Neighbors.html#method.detach
+ pub fn neighbors_directed(&self, a: NodeIndex<Ix>, dir: Direction) -> Neighbors<E, Ix> {
+ let mut iter = self.neighbors_undirected(a);
+ if self.is_directed() {
+ let k = dir.index();
+ iter.next[1 - k] = EdgeIndex::end();
+ iter.skip_start = NodeIndex::end();
+ }
+ iter
+ }
+
+ /// Return an iterator of all neighbors that have an edge between them and `a`,
+ /// in either direction.
+ /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*.
+ ///
+ /// - `Directed` and `Undirected`: All edges connected to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `NodeIndex<Ix>`.
+ ///
+ /// Use [`.neighbors_undirected(a).detach()`][1] to get a neighbor walker that does
+ /// not borrow from the graph.
+ ///
+ /// [1]: struct.Neighbors.html#method.detach
+ pub fn neighbors_undirected(&self, a: NodeIndex<Ix>) -> Neighbors<E, Ix> {
+ Neighbors {
+ skip_start: a,
+ edges: &self.g.edges,
+ next: match self.get_node(a) {
+ None => [EdgeIndex::end(), EdgeIndex::end()],
+ Some(n) => n.next,
+ },
+ }
+ }
+
+ /// Return an iterator of all edges of `a`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges connected to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `EdgeReference<E, Ix>`.
+ pub fn edges(&self, a: NodeIndex<Ix>) -> Edges<E, Ty, Ix> {
+ self.edges_directed(a, Outgoing)
+ }
+
+ /// Return an iterator of all edges of `a`, in the specified direction.
+ ///
+ /// - `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.
+ ///
+ /// Produces an empty iterator if the node `a` doesn't exist.<br>
+ /// Iterator element type is `EdgeReference<E, Ix>`.
+ pub fn edges_directed(&self, a: NodeIndex<Ix>, dir: Direction) -> Edges<E, Ty, Ix> {
+ Edges {
+ skip_start: a,
+ edges: &self.g.edges,
+ direction: dir,
+ next: match self.get_node(a) {
+ None => [EdgeIndex::end(), EdgeIndex::end()],
+ Some(n) => n.next,
+ },
+ ty: PhantomData,
+ }
+ }
+
+ /// Return an iterator over either the nodes without edges to them
+ /// (`Incoming`) or from them (`Outgoing`).
+ ///
+ /// An *internal* node has both incoming and outgoing edges.
+ /// The nodes in `.externals(Incoming)` are the source nodes and
+ /// `.externals(Outgoing)` are the sinks of the graph.
+ ///
+ /// For a graph with undirected edges, both the sinks and the sources are
+ /// just the nodes without edges.
+ ///
+ /// The whole iteration computes in **O(|V|)** time.
+ pub fn externals(&self, dir: Direction) -> Externals<N, Ty, Ix> {
+ Externals {
+ iter: self.raw_nodes().iter().enumerate(),
+ dir,
+ ty: PhantomData,
+ }
+ }
+
+ /// Index the `StableGraph` by two indices, any combination of
+ /// node or edge indices is fine.
+ ///
+ /// **Panics** if the indices are equal or if they are out of bounds.
+ pub fn index_twice_mut<T, U>(
+ &mut self,
+ i: T,
+ j: U,
+ ) -> (
+ &mut <Self as Index<T>>::Output,
+ &mut <Self as Index<U>>::Output,
+ )
+ where
+ Self: IndexMut<T> + IndexMut<U>,
+ T: GraphIndex,
+ U: GraphIndex,
+ {
+ assert!(T::is_node_index() != U::is_node_index() || i.index() != j.index());
+
+ // Allow two mutable indexes here -- they are nonoverlapping
+ unsafe {
+ let self_mut = self as *mut _;
+ (
+ <Self as IndexMut<T>>::index_mut(&mut *self_mut, i),
+ <Self as IndexMut<U>>::index_mut(&mut *self_mut, j),
+ )
+ }
+ }
+
+ /// Keep all nodes that return `true` from the `visit` closure,
+ /// remove the others.
+ ///
+ /// `visit` is provided a proxy reference to the graph, so that
+ /// the graph can be walked and associated data modified.
+ ///
+ /// The order nodes are visited is not specified.
+ ///
+ /// The node indices of the removed nodes are invalidated, but none other.
+ /// Edge indices are invalidated as they would be following the removal of
+ /// each edge with an endpoint in a removed node.
+ ///
+ /// Computes in **O(n + e')** time, where **n** is the number of node indices and
+ /// **e'** is the number of affected edges, including *n* calls to `.remove_edge()`
+ /// where *n* is the number of edges with an endpoint in a removed node.
+ pub fn retain_nodes<F>(&mut self, mut visit: F)
+ where
+ F: FnMut(Frozen<Self>, NodeIndex<Ix>) -> bool,
+ {
+ for i in 0..self.node_bound() {
+ let ix = node_index(i);
+ if self.contains_node(ix) && !visit(Frozen(self), ix) {
+ self.remove_node(ix);
+ }
+ }
+ self.check_free_lists();
+ }
+
+ /// Keep all edges that return `true` from the `visit` closure,
+ /// remove the others.
+ ///
+ /// `visit` is provided a proxy reference to the graph, so that
+ /// the graph can be walked and associated data modified.
+ ///
+ /// The order edges are visited is not specified.
+ ///
+ /// The edge indices of the removed edes are invalidated, but none other.
+ ///
+ /// Computes in **O(e'')** time, **e'** is the number of affected edges,
+ /// including the calls to `.remove_edge()` for each removed edge.
+ pub fn retain_edges<F>(&mut self, mut visit: F)
+ where
+ F: FnMut(Frozen<Self>, EdgeIndex<Ix>) -> bool,
+ {
+ for i in 0..self.edge_bound() {
+ let ix = edge_index(i);
+ if self.edge_weight(ix).is_some() && !visit(Frozen(self), ix) {
+ self.remove_edge(ix);
+ }
+ }
+ self.check_free_lists();
+ }
+
+ /// Create a new `StableGraph` from an iterable of edges.
+ ///
+ /// Node weights `N` are set to default values.
+ /// Edge weights `E` may either be specified in the list,
+ /// or they are filled with default values.
+ ///
+ /// Nodes are inserted automatically to match the edges.
+ ///
+ /// ```
+ /// use petgraph::stable_graph::StableGraph;
+ ///
+ /// let gr = StableGraph::<(), i32>::from_edges(&[
+ /// (0, 1), (0, 2), (0, 3),
+ /// (1, 2), (1, 3),
+ /// (2, 3),
+ /// ]);
+ /// ```
+ pub fn from_edges<I>(iterable: I) -> Self
+ where
+ I: IntoIterator,
+ I::Item: IntoWeightedEdge<E>,
+ <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
+ N: Default,
+ {
+ let mut g = Self::with_capacity(0, 0);
+ g.extend_with_edges(iterable);
+ g
+ }
+
+ /// Create a new `StableGraph` by mapping node and
+ /// edge weights to new values.
+ ///
+ /// The resulting graph has the same structure and the same
+ /// graph indices as `self`.
+ pub fn map<'a, F, G, N2, E2>(
+ &'a self,
+ mut node_map: F,
+ mut edge_map: G,
+ ) -> StableGraph<N2, E2, Ty, Ix>
+ where
+ F: FnMut(NodeIndex<Ix>, &'a N) -> N2,
+ G: FnMut(EdgeIndex<Ix>, &'a E) -> E2,
+ {
+ let g = self.g.map(
+ move |i, w| w.as_ref().map(|w| node_map(i, w)),
+ move |i, w| w.as_ref().map(|w| edge_map(i, w)),
+ );
+ StableGraph {
+ g,
+ node_count: self.node_count,
+ edge_count: self.edge_count,
+ free_node: self.free_node,
+ free_edge: self.free_edge,
+ }
+ }
+
+ /// Create a new `StableGraph` by mapping nodes and edges.
+ /// A node or edge may be mapped to `None` to exclude it from
+ /// the resulting graph.
+ ///
+ /// Nodes are mapped first with the `node_map` closure, then
+ /// `edge_map` is called for the edges that have not had any endpoint
+ /// removed.
+ ///
+ /// The resulting graph has the structure of a subgraph of the original graph.
+ /// Nodes and edges that are not removed maintain their old node or edge
+ /// indices.
+ pub fn filter_map<'a, F, G, N2, E2>(
+ &'a self,
+ mut node_map: F,
+ mut edge_map: G,
+ ) -> StableGraph<N2, E2, Ty, Ix>
+ where
+ F: FnMut(NodeIndex<Ix>, &'a N) -> Option<N2>,
+ G: FnMut(EdgeIndex<Ix>, &'a E) -> Option<E2>,
+ {
+ let node_bound = self.node_bound();
+ let edge_bound = self.edge_bound();
+ let mut result_g = StableGraph::with_capacity(node_bound, edge_bound);
+ // use separate free lists so that
+ // add_node / add_edge below do not reuse the tombstones
+ let mut free_node = NodeIndex::end();
+ let mut free_edge = EdgeIndex::end();
+
+ // the stable graph keeps the node map itself
+
+ for (i, node) in enumerate(self.raw_nodes()) {
+ if i >= node_bound {
+ break;
+ }
+ if let Some(node_weight) = node.weight.as_ref() {
+ if let Some(new_weight) = node_map(NodeIndex::new(i), node_weight) {
+ result_g.add_node(new_weight);
+ continue;
+ }
+ }
+ result_g.add_vacant_node(&mut free_node);
+ }
+ for (i, edge) in enumerate(self.raw_edges()) {
+ if i >= edge_bound {
+ break;
+ }
+ let source = edge.source();
+ let target = edge.target();
+ if let Some(edge_weight) = edge.weight.as_ref() {
+ if result_g.contains_node(source) && result_g.contains_node(target) {
+ if let Some(new_weight) = edge_map(EdgeIndex::new(i), edge_weight) {
+ result_g.add_edge(source, target, new_weight);
+ continue;
+ }
+ }
+ }
+ result_g.add_vacant_edge(&mut free_edge);
+ }
+ result_g.free_node = free_node;
+ result_g.free_edge = free_edge;
+ result_g.check_free_lists();
+ result_g
+ }
+
+ /// Extend the graph from an iterable of edges.
+ ///
+ /// Node weights `N` are set to default values.
+ /// Edge weights `E` may either be specified in the list,
+ /// or they are filled with default values.
+ ///
+ /// Nodes are inserted automatically to match the edges.
+ pub fn extend_with_edges<I>(&mut self, iterable: I)
+ where
+ I: IntoIterator,
+ I::Item: IntoWeightedEdge<E>,
+ <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
+ N: Default,
+ {
+ let iter = iterable.into_iter();
+
+ for elt in iter {
+ let (source, target, weight) = elt.into_weighted_edge();
+ let (source, target) = (source.into(), target.into());
+ let nx = cmp::max(source, target);
+ while nx.index() >= self.node_count() {
+ self.add_node(N::default());
+ }
+ self.add_edge(source, target, weight);
+ }
+ }
+
+ //
+ // internal methods
+ //
+ fn raw_nodes(&self) -> &[Node<Option<N>, Ix>] {
+ self.g.raw_nodes()
+ }
+
+ fn raw_edges(&self) -> &[Edge<Option<E>, Ix>] {
+ self.g.raw_edges()
+ }
+
+ fn edge_bound(&self) -> usize {
+ self.edge_references()
+ .next_back()
+ .map_or(0, |edge| edge.id().index() + 1)
+ }
+
+ #[cfg(feature = "serde-1")]
+ /// Fix up node and edge links after deserialization
+ fn link_edges(&mut self) -> Result<(), NodeIndex<Ix>> {
+ // set up free node list
+ self.node_count = 0;
+ self.edge_count = 0;
+ let mut free_node = NodeIndex::end();
+ for (node_index, node) in enumerate(&mut self.g.nodes) {
+ if node.weight.is_some() {
+ self.node_count += 1;
+ } else {
+ // free node
+ node.next = [free_node._into_edge(), EdgeIndex::end()];
+ free_node = NodeIndex::new(node_index);
+ }
+ }
+ self.free_node = free_node;
+
+ let mut free_edge = EdgeIndex::end();
+ for (edge_index, edge) in enumerate(&mut self.g.edges) {
+ if edge.weight.is_none() {
+ // free edge
+ edge.next = [free_edge, EdgeIndex::end()];
+ free_edge = EdgeIndex::new(edge_index);
+ continue;
+ }
+ let a = edge.source();
+ let b = edge.target();
+ let edge_idx = EdgeIndex::new(edge_index);
+ match index_twice(&mut self.g.nodes, a.index(), b.index()) {
+ Pair::None => return Err(if a > b { a } else { b }),
+ Pair::One(an) => {
+ edge.next = an.next;
+ an.next[0] = edge_idx;
+ an.next[1] = edge_idx;
+ }
+ Pair::Both(an, bn) => {
+ // a and b are different indices
+ edge.next = [an.next[0], bn.next[1]];
+ an.next[0] = edge_idx;
+ bn.next[1] = edge_idx;
+ }
+ }
+ self.edge_count += 1;
+ }
+ self.free_edge = free_edge;
+ Ok(())
+ }
+
+ #[cfg(not(debug_assertions))]
+ fn check_free_lists(&self) {}
+ #[cfg(debug_assertions)]
+ // internal method to debug check the free lists (linked lists)
+ fn check_free_lists(&self) {
+ let mut free_node = self.free_node;
+ let mut free_node_len = 0;
+ while free_node != NodeIndex::end() {
+ if let Some(n) = self.g.nodes.get(free_node.index()) {
+ if n.weight.is_none() {
+ free_node = n.next[0]._into_node();
+ free_node_len += 1;
+ continue;
+ }
+ debug_assert!(
+ false,
+ "Corrupt free list: pointing to existing {:?}",
+ free_node.index()
+ );
+ }
+ debug_assert!(false, "Corrupt free list: missing {:?}", free_node.index());
+ }
+ debug_assert_eq!(self.node_count(), self.raw_nodes().len() - free_node_len);
+
+ let mut free_edge_len = 0;
+ let mut free_edge = self.free_edge;
+ while free_edge != EdgeIndex::end() {
+ if let Some(n) = self.g.edges.get(free_edge.index()) {
+ if n.weight.is_none() {
+ free_edge = n.next[0];
+ free_edge_len += 1;
+ continue;
+ }
+ debug_assert!(
+ false,
+ "Corrupt free list: pointing to existing {:?}",
+ free_node.index()
+ );
+ }
+ debug_assert!(false, "Corrupt free list: missing {:?}", free_edge.index());
+ }
+ debug_assert_eq!(self.edge_count(), self.raw_edges().len() - free_edge_len);
+ }
+}
+
+/// The resulting cloned graph has the same graph indices as `self`.
+impl<N, E, Ty, Ix: IndexType> Clone for StableGraph<N, E, Ty, Ix>
+where
+ N: Clone,
+ E: Clone,
+{
+ fn clone(&self) -> Self {
+ StableGraph {
+ g: self.g.clone(),
+ node_count: self.node_count,
+ edge_count: self.edge_count,
+ free_node: self.free_node,
+ free_edge: self.free_edge,
+ }
+ }
+
+ fn clone_from(&mut self, rhs: &Self) {
+ self.g.clone_from(&rhs.g);
+ self.node_count = rhs.node_count;
+ self.edge_count = rhs.edge_count;
+ self.free_node = rhs.free_node;
+ self.free_edge = rhs.free_edge;
+ }
+}
+
+/// Index the `StableGraph` by `NodeIndex` to access node weights.
+///
+/// **Panics** if the node doesn't exist.
+impl<N, E, Ty, Ix> Index<NodeIndex<Ix>> for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Output = N;
+ fn index(&self, index: NodeIndex<Ix>) -> &N {
+ self.node_weight(index).unwrap()
+ }
+}
+
+/// Index the `StableGraph` by `NodeIndex` to access node weights.
+///
+/// **Panics** if the node doesn't exist.
+impl<N, E, Ty, Ix> IndexMut<NodeIndex<Ix>> for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn index_mut(&mut self, index: NodeIndex<Ix>) -> &mut N {
+ self.node_weight_mut(index).unwrap()
+ }
+}
+
+/// Index the `StableGraph` by `EdgeIndex` to access edge weights.
+///
+/// **Panics** if the edge doesn't exist.
+impl<N, E, Ty, Ix> Index<EdgeIndex<Ix>> for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Output = E;
+ fn index(&self, index: EdgeIndex<Ix>) -> &E {
+ self.edge_weight(index).unwrap()
+ }
+}
+
+/// Index the `StableGraph` by `EdgeIndex` to access edge weights.
+///
+/// **Panics** if the edge doesn't exist.
+impl<N, E, Ty, Ix> IndexMut<EdgeIndex<Ix>> for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn index_mut(&mut self, index: EdgeIndex<Ix>) -> &mut E {
+ self.edge_weight_mut(index).unwrap()
+ }
+}
+
+/// Create a new empty `StableGraph`.
+impl<N, E, Ty, Ix> Default for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn default() -> Self {
+ Self::with_capacity(0, 0)
+ }
+}
+
+/// Convert a `Graph` into a `StableGraph`
+///
+/// Computes in **O(|V| + |E|)** time.
+///
+/// The resulting graph has the same node and edge indices as
+/// the original graph.
+impl<N, E, Ty, Ix> From<Graph<N, E, Ty, Ix>> for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn from(g: Graph<N, E, Ty, Ix>) -> Self {
+ let nodes = g.nodes.into_iter().map(|e| Node {
+ weight: Some(e.weight),
+ next: e.next,
+ });
+ let edges = g.edges.into_iter().map(|e| Edge {
+ weight: Some(e.weight),
+ node: e.node,
+ next: e.next,
+ });
+ StableGraph {
+ node_count: nodes.len(),
+ edge_count: edges.len(),
+ g: Graph {
+ edges: edges.collect(),
+ nodes: nodes.collect(),
+ ty: g.ty,
+ },
+ free_node: NodeIndex::end(),
+ free_edge: EdgeIndex::end(),
+ }
+ }
+}
+
+/// Convert a `StableGraph` into a `Graph`
+///
+/// Computes in **O(|V| + |E|)** time.
+///
+/// This translates the stable graph into a graph with node and edge indices in
+/// a compact interval without holes (like `Graph`s always are).
+///
+/// Only if the stable graph had no vacancies after deletions (if node bound was
+/// equal to node count, and the same for edges), would the resulting graph have
+/// the same node and edge indices as the input.
+impl<N, E, Ty, Ix> From<StableGraph<N, E, Ty, Ix>> for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ fn from(graph: StableGraph<N, E, Ty, Ix>) -> Self {
+ let mut result_g = Graph::with_capacity(graph.node_count(), graph.edge_count());
+ // mapping from old node index to new node index
+ let mut node_index_map = vec![NodeIndex::end(); graph.node_bound()];
+
+ for (i, node) in enumerate(graph.g.nodes) {
+ if let Some(nw) = node.weight {
+ node_index_map[i] = result_g.add_node(nw);
+ }
+ }
+ for edge in graph.g.edges {
+ let source_index = edge.source().index();
+ let target_index = edge.target().index();
+ if let Some(ew) = edge.weight {
+ let source = node_index_map[source_index];
+ let target = node_index_map[target_index];
+ debug_assert!(source != NodeIndex::end());
+ debug_assert!(target != NodeIndex::end());
+ result_g.add_edge(source, target, ew);
+ }
+ }
+ result_g
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoNodeReferences for &'a StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type NodeRef = (NodeIndex<Ix>, &'a N);
+ type NodeReferences = NodeReferences<'a, N, Ix>;
+ fn node_references(self) -> Self::NodeReferences {
+ NodeReferences {
+ iter: enumerate(self.raw_nodes()),
+ }
+ }
+}
+
+/// Iterator over all nodes of a graph.
+pub struct NodeReferences<'a, N: 'a, Ix: IndexType = DefaultIx> {
+ iter: iter::Enumerate<slice::Iter<'a, Node<Option<N>, Ix>>>,
+}
+
+impl<'a, N, Ix> Iterator for NodeReferences<'a, N, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = (NodeIndex<Ix>, &'a N);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter
+ .ex_find_map(|(i, node)| node.weight.as_ref().map(move |w| (node_index(i), w)))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, hi) = self.iter.size_hint();
+ (0, hi)
+ }
+}
+
+impl<'a, N, Ix> DoubleEndedIterator for NodeReferences<'a, N, Ix>
+where
+ Ix: IndexType,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter
+ .ex_rfind_map(|(i, node)| node.weight.as_ref().map(move |w| (node_index(i), w)))
+ }
+}
+
+/// Reference to a `StableGraph` edge.
+#[derive(Debug)]
+pub struct EdgeReference<'a, E: 'a, Ix = DefaultIx> {
+ index: EdgeIndex<Ix>,
+ node: [NodeIndex<Ix>; 2],
+ weight: &'a E,
+}
+
+impl<'a, E, Ix: IndexType> Clone for EdgeReference<'a, E, Ix> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<'a, E, Ix: IndexType> Copy for EdgeReference<'a, E, Ix> {}
+
+impl<'a, E, Ix: IndexType> PartialEq for EdgeReference<'a, E, Ix>
+where
+ E: PartialEq,
+{
+ fn eq(&self, rhs: &Self) -> bool {
+ self.index == rhs.index && self.weight == rhs.weight
+ }
+}
+
+impl<'a, Ix, E> EdgeReference<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ /// Access the edge’s weight.
+ ///
+ /// **NOTE** that this method offers a longer lifetime
+ /// than the trait (unfortunately they don't match yet).
+ pub fn weight(&self) -> &'a E {
+ self.weight
+ }
+}
+
+impl<'a, Ix, E> EdgeRef for EdgeReference<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ type NodeId = NodeIndex<Ix>;
+ type EdgeId = EdgeIndex<Ix>;
+ type Weight = E;
+
+ fn source(&self) -> Self::NodeId {
+ self.node[0]
+ }
+ fn target(&self) -> Self::NodeId {
+ self.node[1]
+ }
+ fn weight(&self) -> &E {
+ self.weight
+ }
+ fn id(&self) -> Self::EdgeId {
+ self.index
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoEdges for &'a StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Edges = Edges<'a, E, Ty, Ix>;
+ fn edges(self, a: Self::NodeId) -> Self::Edges {
+ self.edges(a)
+ }
+}
+
+impl<'a, N, E, Ty, Ix> IntoEdgesDirected for &'a StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type EdgesDirected = Edges<'a, E, Ty, Ix>;
+ fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected {
+ self.edges_directed(a, dir)
+ }
+}
+
+/// Iterator over the edges of from or to a node
+pub struct Edges<'a, E: 'a, Ty, Ix: 'a = DefaultIx>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ /// starting node to skip over
+ skip_start: NodeIndex<Ix>,
+ edges: &'a [Edge<Option<E>, Ix>],
+
+ /// Next edge to visit.
+ next: [EdgeIndex<Ix>; 2],
+
+ /// For directed graphs: the direction to iterate in
+ /// For undirected graphs: the direction of edges
+ direction: Direction,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, E, Ty, Ix> Iterator for Edges<'a, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Item = EdgeReference<'a, E, Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ // type direction | iterate over reverse
+ // |
+ // Directed Outgoing | outgoing no
+ // Directed Incoming | incoming no
+ // Undirected Outgoing | both incoming
+ // Undirected Incoming | both outgoing
+
+ // For iterate_over, "both" is represented as None.
+ // For reverse, "no" is represented as None.
+ let (iterate_over, reverse) = if Ty::is_directed() {
+ (Some(self.direction), None)
+ } else {
+ (None, Some(self.direction.opposite()))
+ };
+
+ if iterate_over.unwrap_or(Outgoing) == Outgoing {
+ let i = self.next[0].index();
+ if let Some(Edge {
+ node,
+ weight: Some(weight),
+ next,
+ }) = self.edges.get(i)
+ {
+ self.next[0] = next[0];
+ return Some(EdgeReference {
+ index: edge_index(i),
+ node: if reverse == Some(Outgoing) {
+ swap_pair(*node)
+ } else {
+ *node
+ },
+ weight,
+ });
+ }
+ }
+
+ if iterate_over.unwrap_or(Incoming) == Incoming {
+ while let Some(Edge { node, weight, next }) = self.edges.get(self.next[1].index()) {
+ debug_assert!(weight.is_some());
+ let edge_index = self.next[1];
+ self.next[1] = next[1];
+ // In any of the "both" situations, self-loops would be iterated over twice.
+ // Skip them here.
+ if iterate_over.is_none() && node[0] == self.skip_start {
+ continue;
+ }
+
+ return Some(EdgeReference {
+ index: edge_index,
+ node: if reverse == Some(Incoming) {
+ swap_pair(*node)
+ } else {
+ *node
+ },
+ weight: weight.as_ref().unwrap(),
+ });
+ }
+ }
+
+ None
+ }
+}
+
+fn swap_pair<T>(mut x: [T; 2]) -> [T; 2] {
+ x.swap(0, 1);
+ x
+}
+
+impl<'a, N: 'a, E: 'a, Ty, Ix> IntoEdgeReferences for &'a StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type EdgeRef = EdgeReference<'a, E, Ix>;
+ type EdgeReferences = EdgeReferences<'a, E, Ix>;
+
+ /// Create an iterator over all edges in the graph, in indexed order.
+ ///
+ /// Iterator element type is `EdgeReference<E, Ix>`.
+ fn edge_references(self) -> Self::EdgeReferences {
+ EdgeReferences {
+ iter: self.g.edges.iter().enumerate(),
+ }
+ }
+}
+
+/// Iterator over all edges of a graph.
+pub struct EdgeReferences<'a, E: 'a, Ix: 'a = DefaultIx> {
+ iter: iter::Enumerate<slice::Iter<'a, Edge<Option<E>, Ix>>>,
+}
+
+impl<'a, E, Ix> Iterator for EdgeReferences<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = EdgeReference<'a, E, Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.ex_find_map(|(i, edge)| {
+ edge.weight.as_ref().map(move |weight| EdgeReference {
+ index: edge_index(i),
+ node: edge.node,
+ weight,
+ })
+ })
+ }
+}
+
+impl<'a, E, Ix> DoubleEndedIterator for EdgeReferences<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.ex_rfind_map(|(i, edge)| {
+ edge.weight.as_ref().map(move |weight| EdgeReference {
+ index: edge_index(i),
+ node: edge.node,
+ weight,
+ })
+ })
+ }
+}
+
+/// An iterator over either the nodes without edges to them or from them.
+pub struct Externals<'a, N: 'a, Ty, Ix: IndexType = DefaultIx> {
+ iter: iter::Enumerate<slice::Iter<'a, Node<Option<N>, Ix>>>,
+ dir: Direction,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, N: 'a, Ty, Ix> Iterator for Externals<'a, N, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type Item = NodeIndex<Ix>;
+ fn next(&mut self) -> Option<NodeIndex<Ix>> {
+ let k = self.dir.index();
+ loop {
+ match self.iter.next() {
+ None => return None,
+ Some((index, node)) => {
+ if node.weight.is_some()
+ && node.next[k] == EdgeIndex::end()
+ && (Ty::is_directed() || node.next[1 - k] == EdgeIndex::end())
+ {
+ return Some(NodeIndex::new(index));
+ } else {
+ continue;
+ }
+ }
+ }
+ }
+ }
+}
+
+/// Iterator over the neighbors of a node.
+///
+/// Iterator element type is `NodeIndex`.
+pub struct Neighbors<'a, E: 'a, Ix: 'a = DefaultIx> {
+ /// starting node to skip over
+ skip_start: NodeIndex<Ix>,
+ edges: &'a [Edge<Option<E>, Ix>],
+ next: [EdgeIndex<Ix>; 2],
+}
+
+impl<'a, E, Ix> Neighbors<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ /// Return a “walker” object that can be used to step through the
+ /// neighbors and edges from the origin node.
+ ///
+ /// Note: The walker does not borrow from the graph, this is to allow mixing
+ /// edge walking with mutating the graph's weights.
+ pub fn detach(&self) -> WalkNeighbors<Ix> {
+ WalkNeighbors {
+ inner: super::WalkNeighbors {
+ skip_start: self.skip_start,
+ next: self.next,
+ },
+ }
+ }
+}
+
+impl<'a, E, Ix> Iterator for Neighbors<'a, E, Ix>
+where
+ Ix: IndexType,
+{
+ type Item = NodeIndex<Ix>;
+
+ fn next(&mut self) -> Option<NodeIndex<Ix>> {
+ // First any outgoing edges
+ match self.edges.get(self.next[0].index()) {
+ None => {}
+ Some(edge) => {
+ debug_assert!(edge.weight.is_some());
+ self.next[0] = edge.next[0];
+ return Some(edge.node[1]);
+ }
+ }
+ // Then incoming edges
+ // For an "undirected" iterator (traverse both incoming
+ // and outgoing edge lists), make sure we don't double
+ // count selfloops by skipping them in the incoming list.
+ while let Some(edge) = self.edges.get(self.next[1].index()) {
+ debug_assert!(edge.weight.is_some());
+ self.next[1] = edge.next[1];
+ if edge.node[0] != self.skip_start {
+ return Some(edge.node[0]);
+ }
+ }
+ None
+ }
+}
+
+/// A “walker” object that can be used to step through the edge list of a node.
+///
+/// See [*.detach()*](struct.Neighbors.html#method.detach) for more information.
+///
+/// The walker does not borrow from the graph, so it lets you step through
+/// neighbors or incident edges while also mutating graph weights, as
+/// in the following example:
+///
+/// ```
+/// use petgraph::visit::Dfs;
+/// use petgraph::Incoming;
+/// use petgraph::stable_graph::StableGraph;
+///
+/// let mut gr = StableGraph::new();
+/// let a = gr.add_node(0.);
+/// let b = gr.add_node(0.);
+/// let c = gr.add_node(0.);
+/// gr.add_edge(a, b, 3.);
+/// gr.add_edge(b, c, 2.);
+/// gr.add_edge(c, b, 1.);
+///
+/// // step through the graph and sum incoming edges into the node weight
+/// let mut dfs = Dfs::new(&gr, a);
+/// while let Some(node) = dfs.next(&gr) {
+/// // use a detached neighbors walker
+/// let mut edges = gr.neighbors_directed(node, Incoming).detach();
+/// while let Some(edge) = edges.next_edge(&gr) {
+/// gr[node] += gr[edge];
+/// }
+/// }
+///
+/// // check the result
+/// assert_eq!(gr[a], 0.);
+/// assert_eq!(gr[b], 4.);
+/// assert_eq!(gr[c], 2.);
+/// ```
+pub struct WalkNeighbors<Ix> {
+ inner: super::WalkNeighbors<Ix>,
+}
+
+impl<Ix: IndexType> Clone for WalkNeighbors<Ix> {
+ clone_fields!(WalkNeighbors, inner);
+}
+
+impl<Ix: IndexType> WalkNeighbors<Ix> {
+ /// Step to the next edge and its endpoint node in the walk for graph `g`.
+ ///
+ /// The next node indices are always the others than the starting point
+ /// where the `WalkNeighbors` value was created.
+ /// For an `Outgoing` walk, the target nodes,
+ /// for an `Incoming` walk, the source nodes of the edge.
+ pub fn next<N, E, Ty: EdgeType>(
+ &mut self,
+ g: &StableGraph<N, E, Ty, Ix>,
+ ) -> Option<(EdgeIndex<Ix>, NodeIndex<Ix>)> {
+ self.inner.next(&g.g)
+ }
+
+ pub fn next_node<N, E, Ty: EdgeType>(
+ &mut self,
+ g: &StableGraph<N, E, Ty, Ix>,
+ ) -> Option<NodeIndex<Ix>> {
+ self.next(g).map(|t| t.1)
+ }
+
+ pub fn next_edge<N, E, Ty: EdgeType>(
+ &mut self,
+ g: &StableGraph<N, E, Ty, Ix>,
+ ) -> Option<EdgeIndex<Ix>> {
+ self.next(g).map(|t| t.0)
+ }
+}
+
+/// Iterator over the node indices of a graph.
+pub struct NodeIndices<'a, N: 'a, Ix: 'a = DefaultIx> {
+ iter: iter::Enumerate<slice::Iter<'a, Node<Option<N>, Ix>>>,
+}
+
+impl<'a, N, Ix: IndexType> Iterator for NodeIndices<'a, N, Ix> {
+ type Item = NodeIndex<Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.ex_find_map(|(i, node)| {
+ if node.weight.is_some() {
+ Some(node_index(i))
+ } else {
+ None
+ }
+ })
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, hi) = self.iter.size_hint();
+ (0, hi)
+ }
+}
+
+impl<'a, N, Ix: IndexType> DoubleEndedIterator for NodeIndices<'a, N, Ix> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.ex_rfind_map(|(i, node)| {
+ if node.weight.is_some() {
+ Some(node_index(i))
+ } else {
+ None
+ }
+ })
+ }
+}
+
+impl<N, E, Ty, Ix> NodeIndexable for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ /// Return an upper bound of the node indices in the graph
+ fn node_bound(&self) -> usize {
+ self.node_indices().next_back().map_or(0, |i| i.index() + 1)
+ }
+ fn to_index(&self, ix: NodeIndex<Ix>) -> usize {
+ ix.index()
+ }
+ fn from_index(&self, ix: usize) -> Self::NodeId {
+ NodeIndex::new(ix)
+ }
+}
+
+/// Iterator over the edge indices of a graph.
+pub struct EdgeIndices<'a, E: 'a, Ix: 'a = DefaultIx> {
+ iter: iter::Enumerate<slice::Iter<'a, Edge<Option<E>, Ix>>>,
+}
+
+impl<'a, E, Ix: IndexType> Iterator for EdgeIndices<'a, E, Ix> {
+ type Item = EdgeIndex<Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.ex_find_map(|(i, node)| {
+ if node.weight.is_some() {
+ Some(edge_index(i))
+ } else {
+ None
+ }
+ })
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, hi) = self.iter.size_hint();
+ (0, hi)
+ }
+}
+
+impl<'a, E, Ix: IndexType> DoubleEndedIterator for EdgeIndices<'a, E, Ix> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.ex_rfind_map(|(i, node)| {
+ if node.weight.is_some() {
+ Some(edge_index(i))
+ } else {
+ None
+ }
+ })
+ }
+}
+
+#[test]
+fn stable_graph() {
+ let mut gr = StableGraph::<_, _>::with_capacity(0, 0);
+ let a = gr.add_node(0);
+ let b = gr.add_node(1);
+ let c = gr.add_node(2);
+ let _ed = gr.add_edge(a, b, 1);
+ println!("{:?}", gr);
+ gr.remove_node(b);
+ println!("{:?}", gr);
+ let d = gr.add_node(3);
+ println!("{:?}", gr);
+ gr.check_free_lists();
+ gr.remove_node(a);
+ gr.check_free_lists();
+ gr.remove_node(c);
+ gr.check_free_lists();
+ println!("{:?}", gr);
+ gr.add_edge(d, d, 2);
+ println!("{:?}", gr);
+
+ let e = gr.add_node(4);
+ gr.add_edge(d, e, 3);
+ println!("{:?}", gr);
+ for neigh in gr.neighbors(d) {
+ println!("edge {:?} -> {:?}", d, neigh);
+ }
+ gr.check_free_lists();
+}
+
+#[test]
+fn dfs() {
+ use crate::visit::Dfs;
+
+ let mut gr = StableGraph::<_, _>::with_capacity(0, 0);
+ let a = gr.add_node("a");
+ let b = gr.add_node("b");
+ let c = gr.add_node("c");
+ let d = gr.add_node("d");
+ gr.add_edge(a, b, 1);
+ gr.add_edge(a, c, 2);
+ gr.add_edge(b, c, 3);
+ gr.add_edge(b, d, 4);
+ gr.add_edge(c, d, 5);
+ gr.add_edge(d, b, 6);
+ gr.add_edge(c, b, 7);
+ println!("{:?}", gr);
+
+ let mut dfs = Dfs::new(&gr, a);
+ while let Some(next) = dfs.next(&gr) {
+ println!("dfs visit => {:?}, weight={:?}", next, &gr[next]);
+ }
+}
+
+#[test]
+fn test_retain_nodes() {
+ let mut gr = StableGraph::<_, _>::with_capacity(6, 6);
+ let a = gr.add_node("a");
+ let f = gr.add_node("f");
+ let b = gr.add_node("b");
+ let c = gr.add_node("c");
+ let d = gr.add_node("d");
+ let e = gr.add_node("e");
+ gr.add_edge(a, b, 1);
+ gr.add_edge(a, c, 2);
+ gr.add_edge(b, c, 3);
+ gr.add_edge(b, d, 4);
+ gr.add_edge(c, d, 5);
+ gr.add_edge(d, b, 6);
+ gr.add_edge(c, b, 7);
+ gr.add_edge(d, e, 8);
+ gr.remove_node(f);
+
+ assert_eq!(gr.node_count(), 5);
+ assert_eq!(gr.edge_count(), 8);
+ gr.retain_nodes(|frozen_gr, ix| frozen_gr[ix] >= "c");
+ assert_eq!(gr.node_count(), 3);
+ assert_eq!(gr.edge_count(), 2);
+
+ gr.check_free_lists();
+}
diff --git a/vendor/petgraph/src/graph_impl/stable_graph/serialization.rs b/vendor/petgraph/src/graph_impl/stable_graph/serialization.rs
new file mode 100644
index 000000000..c24ca636b
--- /dev/null
+++ b/vendor/petgraph/src/graph_impl/stable_graph/serialization.rs
@@ -0,0 +1,296 @@
+use serde::de::Error;
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+use std::marker::PhantomData;
+
+use crate::prelude::*;
+
+use crate::graph::Node;
+use crate::graph::{Edge, IndexType};
+use crate::serde_utils::CollectSeqWithLength;
+use crate::serde_utils::MappedSequenceVisitor;
+use crate::serde_utils::{FromDeserialized, IntoSerializable};
+use crate::stable_graph::StableGraph;
+use crate::util::rev;
+use crate::visit::NodeIndexable;
+use crate::EdgeType;
+
+use super::super::serialization::{invalid_length_err, invalid_node_err, EdgeProperty};
+
+// Serialization representation for StableGraph
+// Keep in sync with deserialization and Graph
+#[derive(Serialize)]
+#[serde(rename = "Graph")]
+#[serde(bound(serialize = "N: Serialize, E: Serialize, Ix: IndexType + Serialize"))]
+pub struct SerStableGraph<'a, N: 'a, E: 'a, Ix: 'a + IndexType> {
+ nodes: Somes<&'a [Node<Option<N>, Ix>]>,
+ node_holes: Holes<&'a [Node<Option<N>, Ix>]>,
+ edge_property: EdgeProperty,
+ #[serde(serialize_with = "ser_stable_graph_edges")]
+ edges: &'a [Edge<Option<E>, Ix>],
+}
+
+// Deserialization representation for StableGraph
+// Keep in sync with serialization and Graph
+#[derive(Deserialize)]
+#[serde(rename = "Graph")]
+#[serde(bound(
+ deserialize = "N: Deserialize<'de>, E: Deserialize<'de>, Ix: IndexType + Deserialize<'de>"
+))]
+pub struct DeserStableGraph<N, E, Ix> {
+ #[serde(deserialize_with = "deser_stable_graph_nodes")]
+ nodes: Vec<Node<Option<N>, Ix>>,
+ #[serde(default = "Vec::new")]
+ node_holes: Vec<NodeIndex<Ix>>,
+ edge_property: EdgeProperty,
+ #[serde(deserialize_with = "deser_stable_graph_edges")]
+ edges: Vec<Edge<Option<E>, Ix>>,
+}
+
+/// `Somes` are the present node weights N, with known length.
+struct Somes<T>(usize, T);
+
+impl<'a, N, Ix> Serialize for Somes<&'a [Node<Option<N>, Ix>]>
+where
+ N: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq_with_length(
+ self.0,
+ self.1.iter().filter_map(|node| node.weight.as_ref()),
+ )
+ }
+}
+
+/// Holes are the node indices of vacancies, with known length
+struct Holes<T>(usize, T);
+
+impl<'a, N, Ix> Serialize for Holes<&'a [Node<Option<N>, Ix>]>
+where
+ Ix: Serialize + IndexType,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq_with_length(
+ self.0,
+ self.1.iter().enumerate().filter_map(|(i, node)| {
+ if node.weight.is_none() {
+ Some(NodeIndex::<Ix>::new(i))
+ } else {
+ None
+ }
+ }),
+ )
+ }
+}
+
+fn ser_stable_graph_edges<S, E, Ix>(
+ edges: &&[Edge<Option<E>, Ix>],
+ serializer: S,
+) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+ E: Serialize,
+ Ix: Serialize + IndexType,
+{
+ serializer.collect_seq_exact(edges.iter().map(|edge| {
+ edge.weight
+ .as_ref()
+ .map(|w| (edge.source(), edge.target(), w))
+ }))
+}
+
+fn deser_stable_graph_nodes<'de, D, N, Ix>(
+ deserializer: D,
+) -> Result<Vec<Node<Option<N>, Ix>>, D::Error>
+where
+ D: Deserializer<'de>,
+ N: Deserialize<'de>,
+ Ix: IndexType + Deserialize<'de>,
+{
+ deserializer.deserialize_seq(MappedSequenceVisitor::new(|n| {
+ Ok(Node {
+ weight: Some(n),
+ next: [EdgeIndex::end(); 2],
+ })
+ }))
+}
+
+fn deser_stable_graph_edges<'de, D, N, Ix>(
+ deserializer: D,
+) -> Result<Vec<Edge<Option<N>, Ix>>, D::Error>
+where
+ D: Deserializer<'de>,
+ N: Deserialize<'de>,
+ Ix: IndexType + Deserialize<'de>,
+{
+ deserializer.deserialize_seq(MappedSequenceVisitor::<
+ Option<(NodeIndex<Ix>, NodeIndex<Ix>, N)>,
+ _,
+ _,
+ >::new(|x| {
+ if let Some((i, j, w)) = x {
+ Ok(Edge {
+ weight: Some(w),
+ node: [i, j],
+ next: [EdgeIndex::end(); 2],
+ })
+ } else {
+ Ok(Edge {
+ weight: None,
+ node: [NodeIndex::end(); 2],
+ next: [EdgeIndex::end(); 2],
+ })
+ }
+ }))
+}
+
+impl<'a, N, E, Ty, Ix> IntoSerializable for &'a StableGraph<N, E, Ty, Ix>
+where
+ Ix: IndexType,
+ Ty: EdgeType,
+{
+ type Output = SerStableGraph<'a, N, E, Ix>;
+ fn into_serializable(self) -> Self::Output {
+ let nodes = &self.raw_nodes()[..self.node_bound()];
+ let node_count = self.node_count();
+ let hole_count = nodes.len() - node_count;
+ let edges = &self.raw_edges()[..self.edge_bound()];
+ SerStableGraph {
+ nodes: Somes(node_count, nodes),
+ node_holes: Holes(hole_count, nodes),
+ edges: edges,
+ edge_property: EdgeProperty::from(PhantomData::<Ty>),
+ }
+ }
+}
+
+/// Requires crate feature `"serde-1"`
+impl<N, E, Ty, Ix> Serialize for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType + Serialize,
+ N: Serialize,
+ E: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.into_serializable().serialize(serializer)
+ }
+}
+
+impl<'a, N, E, Ty, Ix> FromDeserialized for StableGraph<N, E, Ty, Ix>
+where
+ Ix: IndexType,
+ Ty: EdgeType,
+{
+ type Input = DeserStableGraph<N, E, Ix>;
+ fn from_deserialized<E2>(input: Self::Input) -> Result<Self, E2>
+ where
+ E2: Error,
+ {
+ let ty = PhantomData::<Ty>::from_deserialized(input.edge_property)?;
+ let mut nodes = input.nodes;
+ let node_holes = input.node_holes;
+ let edges = input.edges;
+ if edges.len() >= <Ix as IndexType>::max().index() {
+ Err(invalid_length_err::<Ix, _>("edge", edges.len()))?
+ }
+
+ // insert Nones for each hole
+ let mut offset = node_holes.len();
+ let node_bound = node_holes.len() + nodes.len();
+ for hole_pos in rev(node_holes) {
+ offset -= 1;
+ if hole_pos.index() >= node_bound {
+ Err(invalid_node_err(hole_pos.index(), node_bound))?;
+ }
+ let insert_pos = hole_pos.index() - offset;
+ nodes.insert(
+ insert_pos,
+ Node {
+ weight: None,
+ next: [EdgeIndex::end(); 2],
+ },
+ );
+ }
+
+ if nodes.len() >= <Ix as IndexType>::max().index() {
+ Err(invalid_length_err::<Ix, _>("node", nodes.len()))?
+ }
+
+ let node_bound = nodes.len();
+ let mut sgr = StableGraph {
+ g: Graph {
+ nodes: nodes,
+ edges: edges,
+ ty: ty,
+ },
+ node_count: 0,
+ edge_count: 0,
+ free_edge: EdgeIndex::end(),
+ free_node: NodeIndex::end(),
+ };
+ sgr.link_edges()
+ .map_err(|i| invalid_node_err(i.index(), node_bound))?;
+ Ok(sgr)
+ }
+}
+
+/// Requires crate feature `"serde-1"`
+impl<'de, N, E, Ty, Ix> Deserialize<'de> for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType + Deserialize<'de>,
+ N: Deserialize<'de>,
+ E: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Self::from_deserialized(DeserStableGraph::deserialize(deserializer)?)
+ }
+}
+
+#[test]
+fn test_from_deserialized_with_holes() {
+ use crate::graph::node_index;
+ use crate::stable_graph::StableUnGraph;
+ use itertools::assert_equal;
+ use serde::de::value::Error as SerdeError;
+
+ let input = DeserStableGraph::<_, (), u32> {
+ nodes: vec![
+ Node {
+ weight: Some(1),
+ next: [EdgeIndex::end(); 2],
+ },
+ Node {
+ weight: Some(4),
+ next: [EdgeIndex::end(); 2],
+ },
+ Node {
+ weight: Some(5),
+ next: [EdgeIndex::end(); 2],
+ },
+ ],
+ node_holes: vec![node_index(0), node_index(2), node_index(3), node_index(6)],
+ edges: vec![],
+ edge_property: EdgeProperty::Undirected,
+ };
+ let graph = StableUnGraph::from_deserialized::<SerdeError>(input).unwrap();
+
+ assert_eq!(graph.node_count(), 3);
+ assert_equal(
+ graph.raw_nodes().iter().map(|n| n.weight.as_ref().cloned()),
+ vec![None, Some(1), None, None, Some(4), Some(5), None],
+ );
+}
diff --git a/vendor/petgraph/src/graphmap.rs b/vendor/petgraph/src/graphmap.rs
new file mode 100644
index 000000000..3905ea2f9
--- /dev/null
+++ b/vendor/petgraph/src/graphmap.rs
@@ -0,0 +1,947 @@
+//! `GraphMap<N, E, Ty>` is a graph datastructure where node values are mapping
+//! keys.
+
+use indexmap::map::Keys;
+use indexmap::map::{Iter as IndexMapIter, IterMut as IndexMapIterMut};
+use indexmap::IndexMap;
+use std::cmp::Ordering;
+use std::fmt;
+use std::hash::{self, Hash};
+use std::iter::FromIterator;
+use std::iter::{Cloned, DoubleEndedIterator};
+use std::marker::PhantomData;
+use std::ops::{Deref, Index, IndexMut};
+use std::slice::Iter;
+
+use crate::{Directed, Direction, EdgeType, Incoming, Outgoing, Undirected};
+
+use crate::graph::node_index;
+use crate::graph::Graph;
+use crate::visit::{IntoEdgeReferences, IntoEdges, NodeCompactIndexable};
+use crate::visit::{IntoNodeIdentifiers, IntoNodeReferences, NodeCount, NodeIndexable};
+use crate::IntoWeightedEdge;
+
+/// A `GraphMap` with undirected edges.
+///
+/// For example, an edge between *1* and *2* is equivalent to an edge between
+/// *2* and *1*.
+pub type UnGraphMap<N, E> = GraphMap<N, E, Undirected>;
+/// A `GraphMap` with directed edges.
+///
+/// For example, an edge from *1* to *2* is distinct from an edge from *2* to
+/// *1*.
+pub type DiGraphMap<N, E> = GraphMap<N, E, Directed>;
+
+/// `GraphMap<N, E, Ty>` is a graph datastructure using an associative array
+/// of its node weights `N`.
+///
+/// It uses an combined adjacency list and sparse adjacency matrix
+/// representation, using **O(|V| + |E|)** space, and allows testing for edge
+/// existence in constant time.
+///
+/// `GraphMap` is parameterized over:
+///
+/// - Associated data `N` for nodes and `E` for edges, called *weights*.
+/// - The node weight `N` must implement `Copy` and will be used as node
+/// identifier, duplicated into several places in the data structure.
+/// It must be suitable as a hash table key (implementing `Eq + Hash`).
+/// The node type must also implement `Ord` so that the implementation can
+/// order the pair (`a`, `b`) for an edge connecting any two nodes `a` and `b`.
+/// - `E` can be of arbitrary type.
+/// - Edge type `Ty` that determines whether the graph edges are directed or
+/// undirected.
+///
+/// You can use the type aliases `UnGraphMap` and `DiGraphMap` for convenience.
+///
+/// `GraphMap` does not allow parallel edges, but self loops are allowed.
+///
+/// Depends on crate feature `graphmap` (default).
+#[derive(Clone)]
+pub struct GraphMap<N, E, Ty> {
+ nodes: IndexMap<N, Vec<(N, CompactDirection)>>,
+ edges: IndexMap<(N, N), E>,
+ ty: PhantomData<Ty>,
+}
+
+impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug, Ty: EdgeType> fmt::Debug for GraphMap<N, E, Ty> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.nodes.fmt(f)
+ }
+}
+
+/// A trait group for `GraphMap`'s node identifier.
+pub trait NodeTrait: Copy + Ord + Hash {}
+impl<N> NodeTrait for N where N: Copy + Ord + Hash {}
+
+// non-repr(usize) version of Direction
+#[derive(Copy, Clone, Debug, PartialEq)]
+enum CompactDirection {
+ Outgoing,
+ Incoming,
+}
+
+impl From<Direction> for CompactDirection {
+ fn from(d: Direction) -> Self {
+ match d {
+ Outgoing => CompactDirection::Outgoing,
+ Incoming => CompactDirection::Incoming,
+ }
+ }
+}
+
+impl PartialEq<Direction> for CompactDirection {
+ fn eq(&self, rhs: &Direction) -> bool {
+ (*self as usize) == (*rhs as usize)
+ }
+}
+
+impl<N, E, Ty> GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ /// Create a new `GraphMap`
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ /// Create a new `GraphMap` with estimated capacity.
+ pub fn with_capacity(nodes: usize, edges: usize) -> Self {
+ GraphMap {
+ nodes: IndexMap::with_capacity(nodes),
+ edges: IndexMap::with_capacity(edges),
+ ty: PhantomData,
+ }
+ }
+
+ /// Return the current node and edge capacity of the graph.
+ pub fn capacity(&self) -> (usize, usize) {
+ (self.nodes.capacity(), self.edges.capacity())
+ }
+
+ /// Use their natural order to map the node pair (a, b) to a canonical edge id.
+ #[inline]
+ fn edge_key(a: N, b: N) -> (N, N) {
+ if Ty::is_directed() || a <= b {
+ (a, b)
+ } else {
+ (b, a)
+ }
+ }
+
+ /// Whether the graph has directed edges.
+ pub fn is_directed(&self) -> bool {
+ Ty::is_directed()
+ }
+
+ /// Create a new `GraphMap` from an iterable of edges.
+ ///
+ /// Node values are taken directly from the list.
+ /// Edge weights `E` may either be specified in the list,
+ /// or they are filled with default values.
+ ///
+ /// Nodes are inserted automatically to match the edges.
+ ///
+ /// ```
+ /// use petgraph::graphmap::UnGraphMap;
+ ///
+ /// // Create a new undirected GraphMap.
+ /// // Use a type hint to have `()` be the edge weight type.
+ /// let gr = UnGraphMap::<_, ()>::from_edges(&[
+ /// (0, 1), (0, 2), (0, 3),
+ /// (1, 2), (1, 3),
+ /// (2, 3),
+ /// ]);
+ /// ```
+ pub fn from_edges<I>(iterable: I) -> Self
+ where
+ I: IntoIterator,
+ I::Item: IntoWeightedEdge<E, NodeId = N>,
+ {
+ Self::from_iter(iterable)
+ }
+
+ /// Return the number of nodes in the graph.
+ pub fn node_count(&self) -> usize {
+ self.nodes.len()
+ }
+
+ /// Return the number of edges in the graph.
+ pub fn edge_count(&self) -> usize {
+ self.edges.len()
+ }
+
+ /// Remove all nodes and edges
+ pub fn clear(&mut self) {
+ self.nodes.clear();
+ self.edges.clear();
+ }
+
+ /// Add node `n` to the graph.
+ pub fn add_node(&mut self, n: N) -> N {
+ self.nodes.entry(n).or_insert(Vec::new());
+ n
+ }
+
+ /// Return `true` if node `n` was removed.
+ ///
+ /// Computes in **O(V)** time, due to the removal of edges with other nodes.
+ pub fn remove_node(&mut self, n: N) -> bool {
+ let links = match self.nodes.swap_remove(&n) {
+ None => return false,
+ Some(sus) => sus,
+ };
+ for (succ, _) in links {
+ // remove all successor links
+ self.remove_single_edge(&succ, &n, Incoming);
+ // Remove all edge values
+ self.edges.swap_remove(&Self::edge_key(n, succ));
+ }
+ true
+ }
+
+ /// Return `true` if the node is contained in the graph.
+ pub fn contains_node(&self, n: N) -> bool {
+ self.nodes.contains_key(&n)
+ }
+
+ /// Add an edge connecting `a` and `b` to the graph, with associated
+ /// data `weight`. For a directed graph, the edge is directed from `a`
+ /// to `b`.
+ ///
+ /// Inserts nodes `a` and/or `b` if they aren't already part of the graph.
+ ///
+ /// Return `None` if the edge did not previously exist, otherwise,
+ /// the associated data is updated and the old value is returned
+ /// as `Some(old_weight)`.
+ ///
+ /// ```
+ /// // Create a GraphMap with directed edges, and add one edge to it
+ /// use petgraph::graphmap::DiGraphMap;
+ ///
+ /// let mut g = DiGraphMap::new();
+ /// g.add_edge("x", "y", -1);
+ /// assert_eq!(g.node_count(), 2);
+ /// assert_eq!(g.edge_count(), 1);
+ /// assert!(g.contains_edge("x", "y"));
+ /// assert!(!g.contains_edge("y", "x"));
+ /// ```
+ pub fn add_edge(&mut self, a: N, b: N, weight: E) -> Option<E> {
+ if let old @ Some(_) = self.edges.insert(Self::edge_key(a, b), weight) {
+ old
+ } else {
+ // insert in the adjacency list if it's a new edge
+ self.nodes
+ .entry(a)
+ .or_insert_with(|| Vec::with_capacity(1))
+ .push((b, CompactDirection::Outgoing));
+ if a != b {
+ // self loops don't have the Incoming entry
+ self.nodes
+ .entry(b)
+ .or_insert_with(|| Vec::with_capacity(1))
+ .push((a, CompactDirection::Incoming));
+ }
+ None
+ }
+ }
+
+ /// Remove edge relation from a to b
+ ///
+ /// Return `true` if it did exist.
+ fn remove_single_edge(&mut self, a: &N, b: &N, dir: Direction) -> bool {
+ match self.nodes.get_mut(a) {
+ None => false,
+ Some(sus) => {
+ if Ty::is_directed() {
+ match sus
+ .iter()
+ .position(|elt| elt == &(*b, CompactDirection::from(dir)))
+ {
+ Some(index) => {
+ sus.swap_remove(index);
+ true
+ }
+ None => false,
+ }
+ } else {
+ match sus.iter().position(|elt| &elt.0 == b) {
+ Some(index) => {
+ sus.swap_remove(index);
+ true
+ }
+ None => false,
+ }
+ }
+ }
+ }
+ }
+
+ /// Remove edge from `a` to `b` from the graph and return the edge weight.
+ ///
+ /// Return `None` if the edge didn't exist.
+ ///
+ /// ```
+ /// // Create a GraphMap with undirected edges, and add and remove an edge.
+ /// use petgraph::graphmap::UnGraphMap;
+ ///
+ /// let mut g = UnGraphMap::new();
+ /// g.add_edge("x", "y", -1);
+ ///
+ /// let edge_data = g.remove_edge("y", "x");
+ /// assert_eq!(edge_data, Some(-1));
+ /// assert_eq!(g.edge_count(), 0);
+ /// ```
+ pub fn remove_edge(&mut self, a: N, b: N) -> Option<E> {
+ let exist1 = self.remove_single_edge(&a, &b, Outgoing);
+ let exist2 = if a != b {
+ self.remove_single_edge(&b, &a, Incoming)
+ } else {
+ exist1
+ };
+ let weight = self.edges.remove(&Self::edge_key(a, b));
+ debug_assert!(exist1 == exist2 && exist1 == weight.is_some());
+ weight
+ }
+
+ /// Return `true` if the edge connecting `a` with `b` is contained in the graph.
+ pub fn contains_edge(&self, a: N, b: N) -> bool {
+ self.edges.contains_key(&Self::edge_key(a, b))
+ }
+
+ /// Return an iterator over the nodes of the graph.
+ ///
+ /// Iterator element type is `N`.
+ pub fn nodes(&self) -> Nodes<N> {
+ Nodes {
+ iter: self.nodes.keys().cloned(),
+ }
+ }
+
+ /// Return an iterator of all nodes with an edge starting from `a`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges from or to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `N`.
+ pub fn neighbors(&self, a: N) -> Neighbors<N, Ty> {
+ Neighbors {
+ iter: match self.nodes.get(&a) {
+ Some(neigh) => neigh.iter(),
+ None => [].iter(),
+ },
+ ty: self.ty,
+ }
+ }
+
+ /// Return an iterator of all neighbors that have an edge between them and
+ /// `a`, in the specified direction.
+ /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*.
+ ///
+ /// - `Directed`, `Outgoing`: All edges from `a`.
+ /// - `Directed`, `Incoming`: All edges to `a`.
+ /// - `Undirected`: All edges from or to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `N`.
+ pub fn neighbors_directed(&self, a: N, dir: Direction) -> NeighborsDirected<N, Ty> {
+ NeighborsDirected {
+ iter: match self.nodes.get(&a) {
+ Some(neigh) => neigh.iter(),
+ None => [].iter(),
+ },
+ start_node: a,
+ dir,
+ ty: self.ty,
+ }
+ }
+
+ /// Return an iterator of target nodes with an edge starting from `a`,
+ /// paired with their respective edge weights.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges from or to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is `(N, &E)`.
+ pub fn edges(&self, from: N) -> Edges<N, E, Ty> {
+ Edges {
+ from,
+ iter: self.neighbors(from),
+ edges: &self.edges,
+ }
+ }
+
+ /// Return a reference to the edge weight connecting `a` with `b`, or
+ /// `None` if the edge does not exist in the graph.
+ pub fn edge_weight(&self, a: N, b: N) -> Option<&E> {
+ self.edges.get(&Self::edge_key(a, b))
+ }
+
+ /// Return a mutable reference to the edge weight connecting `a` with `b`, or
+ /// `None` if the edge does not exist in the graph.
+ pub fn edge_weight_mut(&mut self, a: N, b: N) -> Option<&mut E> {
+ self.edges.get_mut(&Self::edge_key(a, b))
+ }
+
+ /// Return an iterator over all edges of the graph with their weight in arbitrary order.
+ ///
+ /// Iterator element type is `(N, N, &E)`
+ pub fn all_edges(&self) -> AllEdges<N, E, Ty> {
+ AllEdges {
+ inner: self.edges.iter(),
+ ty: self.ty,
+ }
+ }
+
+ /// Return an iterator over all edges of the graph in arbitrary order, with a mutable reference
+ /// to their weight.
+ ///
+ /// Iterator element type is `(N, N, &mut E)`
+ pub fn all_edges_mut(&mut self) -> AllEdgesMut<N, E, Ty> {
+ AllEdgesMut {
+ inner: self.edges.iter_mut(),
+ ty: self.ty,
+ }
+ }
+
+ /// Return a `Graph` that corresponds to this `GraphMap`.
+ ///
+ /// 1. Note that node and edge indices in the `Graph` have nothing in common
+ /// with the `GraphMap`s node weights `N`. The node weights `N` are used as
+ /// node weights in the resulting `Graph`, too.
+ /// 2. Note that the index type is user-chosen.
+ ///
+ /// Computes in **O(|V| + |E|)** time (average).
+ ///
+ /// **Panics** if the number of nodes or edges does not fit with
+ /// the resulting graph's index type.
+ pub fn into_graph<Ix>(self) -> Graph<N, E, Ty, Ix>
+ where
+ Ix: crate::graph::IndexType,
+ {
+ // assuming two successive iterations of the same hashmap produce the same order
+ let mut gr = Graph::with_capacity(self.node_count(), self.edge_count());
+ for (&node, _) in &self.nodes {
+ gr.add_node(node);
+ }
+ for ((a, b), edge_weight) in self.edges {
+ let (ai, _, _) = self.nodes.get_full(&a).unwrap();
+ let (bi, _, _) = self.nodes.get_full(&b).unwrap();
+ gr.add_edge(node_index(ai), node_index(bi), edge_weight);
+ }
+ gr
+ }
+}
+
+/// Create a new `GraphMap` from an iterable of edges.
+impl<N, E, Ty, Item> FromIterator<Item> for GraphMap<N, E, Ty>
+where
+ Item: IntoWeightedEdge<E, NodeId = N>,
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ fn from_iter<I>(iterable: I) -> Self
+ where
+ I: IntoIterator<Item = Item>,
+ {
+ let iter = iterable.into_iter();
+ let (low, _) = iter.size_hint();
+ let mut g = Self::with_capacity(0, low);
+ g.extend(iter);
+ g
+ }
+}
+
+/// Extend the graph from an iterable of edges.
+///
+/// Nodes are inserted automatically to match the edges.
+impl<N, E, Ty, Item> Extend<Item> for GraphMap<N, E, Ty>
+where
+ Item: IntoWeightedEdge<E, NodeId = N>,
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ fn extend<I>(&mut self, iterable: I)
+ where
+ I: IntoIterator<Item = Item>,
+ {
+ let iter = iterable.into_iter();
+ let (low, _) = iter.size_hint();
+ self.edges.reserve(low);
+
+ for elt in iter {
+ let (source, target, weight) = elt.into_weighted_edge();
+ self.add_edge(source, target, weight);
+ }
+ }
+}
+
+macro_rules! iterator_wrap {
+ ($name: ident <$($typarm:tt),*> where { $($bounds: tt)* }
+ item: $item: ty,
+ iter: $iter: ty,
+ ) => (
+ pub struct $name <$($typarm),*> where $($bounds)* {
+ iter: $iter,
+ }
+ impl<$($typarm),*> Iterator for $name <$($typarm),*>
+ where $($bounds)*
+ {
+ type Item = $item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+ }
+ );
+}
+
+iterator_wrap! {
+ Nodes <'a, N> where { N: 'a + NodeTrait }
+ item: N,
+ iter: Cloned<Keys<'a, N, Vec<(N, CompactDirection)>>>,
+}
+
+pub struct Neighbors<'a, N, Ty = Undirected>
+where
+ N: 'a,
+ Ty: EdgeType,
+{
+ iter: Iter<'a, (N, CompactDirection)>,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, N, Ty> Iterator for Neighbors<'a, N, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ type Item = N;
+ fn next(&mut self) -> Option<N> {
+ if Ty::is_directed() {
+ (&mut self.iter)
+ .filter_map(|&(n, dir)| if dir == Outgoing { Some(n) } else { None })
+ .next()
+ } else {
+ self.iter.next().map(|&(n, _)| n)
+ }
+ }
+}
+
+pub struct NeighborsDirected<'a, N, Ty>
+where
+ N: 'a,
+ Ty: EdgeType,
+{
+ iter: Iter<'a, (N, CompactDirection)>,
+ start_node: N,
+ dir: Direction,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, N, Ty> Iterator for NeighborsDirected<'a, N, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ type Item = N;
+ fn next(&mut self) -> Option<N> {
+ if Ty::is_directed() {
+ let self_dir = self.dir;
+ let start_node = self.start_node;
+ (&mut self.iter)
+ .filter_map(move |&(n, dir)| {
+ if dir == self_dir || n == start_node {
+ Some(n)
+ } else {
+ None
+ }
+ })
+ .next()
+ } else {
+ self.iter.next().map(|&(n, _)| n)
+ }
+ }
+}
+
+pub struct Edges<'a, N, E: 'a, Ty>
+where
+ N: 'a + NodeTrait,
+ Ty: EdgeType,
+{
+ from: N,
+ edges: &'a IndexMap<(N, N), E>,
+ iter: Neighbors<'a, N, Ty>,
+}
+
+impl<'a, N, E, Ty> Iterator for Edges<'a, N, E, Ty>
+where
+ N: 'a + NodeTrait,
+ E: 'a,
+ Ty: EdgeType,
+{
+ type Item = (N, N, &'a E);
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.iter.next() {
+ None => None,
+ Some(b) => {
+ let a = self.from;
+ match self.edges.get(&GraphMap::<N, E, Ty>::edge_key(a, b)) {
+ None => unreachable!(),
+ Some(edge) => Some((a, b, edge)),
+ }
+ }
+ }
+ }
+}
+
+impl<'a, N: 'a, E: 'a, Ty> IntoEdgeReferences for &'a GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ type EdgeRef = (N, N, &'a E);
+ type EdgeReferences = AllEdges<'a, N, E, Ty>;
+ fn edge_references(self) -> Self::EdgeReferences {
+ self.all_edges()
+ }
+}
+
+pub struct AllEdges<'a, N, E: 'a, Ty>
+where
+ N: 'a + NodeTrait,
+{
+ inner: IndexMapIter<'a, (N, N), E>,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, N, E, Ty> Iterator for AllEdges<'a, N, E, Ty>
+where
+ N: 'a + NodeTrait,
+ E: 'a,
+ Ty: EdgeType,
+{
+ type Item = (N, N, &'a E);
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.inner.next() {
+ None => None,
+ Some((&(a, b), v)) => Some((a, b, v)),
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+
+ fn count(self) -> usize {
+ self.inner.count()
+ }
+
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.inner
+ .nth(n)
+ .map(|(&(n1, n2), weight)| (n1, n2, weight))
+ }
+
+ fn last(self) -> Option<Self::Item> {
+ self.inner
+ .last()
+ .map(|(&(n1, n2), weight)| (n1, n2, weight))
+ }
+}
+
+impl<'a, N, E, Ty> DoubleEndedIterator for AllEdges<'a, N, E, Ty>
+where
+ N: 'a + NodeTrait,
+ E: 'a,
+ Ty: EdgeType,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.inner
+ .next_back()
+ .map(|(&(n1, n2), weight)| (n1, n2, weight))
+ }
+}
+
+pub struct AllEdgesMut<'a, N, E: 'a, Ty>
+where
+ N: 'a + NodeTrait,
+{
+ inner: IndexMapIterMut<'a, (N, N), E>,
+ ty: PhantomData<Ty>,
+}
+
+impl<'a, N, E, Ty> Iterator for AllEdgesMut<'a, N, E, Ty>
+where
+ N: 'a + NodeTrait,
+ E: 'a,
+ Ty: EdgeType,
+{
+ type Item = (N, N, &'a mut E);
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner
+ .next()
+ .map(|(&(n1, n2), weight)| (n1, n2, weight))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+
+ fn count(self) -> usize {
+ self.inner.count()
+ }
+
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.inner
+ .nth(n)
+ .map(|(&(n1, n2), weight)| (n1, n2, weight))
+ }
+
+ fn last(self) -> Option<Self::Item> {
+ self.inner
+ .last()
+ .map(|(&(n1, n2), weight)| (n1, n2, weight))
+ }
+}
+
+impl<'a, N, E, Ty> DoubleEndedIterator for AllEdgesMut<'a, N, E, Ty>
+where
+ N: 'a + NodeTrait,
+ E: 'a,
+ Ty: EdgeType,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.inner
+ .next_back()
+ .map(|(&(n1, n2), weight)| (n1, n2, weight))
+ }
+}
+
+impl<'a, N: 'a, E: 'a, Ty> IntoEdges for &'a GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ type Edges = Edges<'a, N, E, Ty>;
+ fn edges(self, a: Self::NodeId) -> Self::Edges {
+ self.edges(a)
+ }
+}
+
+/// Index `GraphMap` by node pairs to access edge weights.
+impl<N, E, Ty> Index<(N, N)> for GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ type Output = E;
+ fn index(&self, index: (N, N)) -> &E {
+ let index = Self::edge_key(index.0, index.1);
+ self.edge_weight(index.0, index.1)
+ .expect("GraphMap::index: no such edge")
+ }
+}
+
+/// Index `GraphMap` by node pairs to access edge weights.
+impl<N, E, Ty> IndexMut<(N, N)> for GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ fn index_mut(&mut self, index: (N, N)) -> &mut E {
+ let index = Self::edge_key(index.0, index.1);
+ self.edge_weight_mut(index.0, index.1)
+ .expect("GraphMap::index: no such edge")
+ }
+}
+
+/// Create a new empty `GraphMap`.
+impl<N, E, Ty> Default for GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ fn default() -> Self {
+ GraphMap::with_capacity(0, 0)
+ }
+}
+
+/// A reference that is hashed and compared by its pointer value.
+///
+/// `Ptr` is used for certain configurations of `GraphMap`,
+/// in particular in the combination where the node type for
+/// `GraphMap` is something of type for example `Ptr(&Cell<T>)`,
+/// with the `Cell<T>` being `TypedArena` allocated.
+pub struct Ptr<'b, T: 'b>(pub &'b T);
+
+impl<'b, T> Copy for Ptr<'b, T> {}
+impl<'b, T> Clone for Ptr<'b, T> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
+ a == b
+}
+
+impl<'b, T> PartialEq for Ptr<'b, T> {
+ /// Ptr compares by pointer equality, i.e if they point to the same value
+ fn eq(&self, other: &Ptr<'b, T>) -> bool {
+ ptr_eq(self.0, other.0)
+ }
+}
+
+impl<'b, T> PartialOrd for Ptr<'b, T> {
+ fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl<'b, T> Ord for Ptr<'b, T> {
+ /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
+ fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
+ let a: *const T = self.0;
+ let b: *const T = other.0;
+ a.cmp(&b)
+ }
+}
+
+impl<'b, T> Deref for Ptr<'b, T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ self.0
+ }
+}
+
+impl<'b, T> Eq for Ptr<'b, T> {}
+
+impl<'b, T> Hash for Ptr<'b, T> {
+ fn hash<H: hash::Hasher>(&self, st: &mut H) {
+ let ptr = (self.0) as *const T;
+ ptr.hash(st)
+ }
+}
+
+impl<'b, T: fmt::Debug> fmt::Debug for Ptr<'b, T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+impl<'a, N, E: 'a, Ty> IntoNodeIdentifiers for &'a GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ type NodeIdentifiers = NodeIdentifiers<'a, N, E, Ty>;
+
+ fn node_identifiers(self) -> Self::NodeIdentifiers {
+ NodeIdentifiers {
+ iter: self.nodes.iter(),
+ ty: self.ty,
+ edge_ty: PhantomData,
+ }
+ }
+}
+
+impl<N, E, Ty> NodeCount for GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ fn node_count(&self) -> usize {
+ (*self).node_count()
+ }
+}
+
+pub struct NodeIdentifiers<'a, N, E: 'a, Ty>
+where
+ N: 'a + NodeTrait,
+{
+ iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
+ ty: PhantomData<Ty>,
+ edge_ty: PhantomData<E>,
+}
+
+impl<'a, N, E, Ty> Iterator for NodeIdentifiers<'a, N, E, Ty>
+where
+ N: 'a + NodeTrait,
+ E: 'a,
+ Ty: EdgeType,
+{
+ type Item = N;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(|(&n, _)| n)
+ }
+}
+
+impl<'a, N, E, Ty> IntoNodeReferences for &'a GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ type NodeRef = (N, &'a N);
+ type NodeReferences = NodeReferences<'a, N, E, Ty>;
+ fn node_references(self) -> Self::NodeReferences {
+ NodeReferences {
+ iter: self.nodes.iter(),
+ ty: self.ty,
+ edge_ty: PhantomData,
+ }
+ }
+}
+
+pub struct NodeReferences<'a, N, E: 'a, Ty>
+where
+ N: 'a + NodeTrait,
+{
+ iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
+ ty: PhantomData<Ty>,
+ edge_ty: PhantomData<E>,
+}
+
+impl<'a, N, E, Ty> Iterator for NodeReferences<'a, N, E, Ty>
+where
+ N: 'a + NodeTrait,
+ E: 'a,
+ Ty: EdgeType,
+{
+ type Item = (N, &'a N);
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(|(n, _)| (*n, n))
+ }
+}
+
+impl<N, E, Ty> NodeIndexable for GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+ fn node_bound(&self) -> usize {
+ self.node_count()
+ }
+ fn to_index(&self, ix: Self::NodeId) -> usize {
+ let (i, _, _) = self.nodes.get_full(&ix).unwrap();
+ i
+ }
+ fn from_index(&self, ix: usize) -> Self::NodeId {
+ let (&key, _) = self.nodes.get_index(ix).unwrap();
+ key
+ }
+}
+
+impl<N, E, Ty> NodeCompactIndexable for GraphMap<N, E, Ty>
+where
+ N: NodeTrait,
+ Ty: EdgeType,
+{
+}
diff --git a/vendor/petgraph/src/isomorphism.rs b/vendor/petgraph/src/isomorphism.rs
new file mode 100644
index 000000000..1d2cd2736
--- /dev/null
+++ b/vendor/petgraph/src/isomorphism.rs
@@ -0,0 +1,525 @@
+use fixedbitset::FixedBitSet;
+use std::marker;
+
+use super::graph::{Graph, IndexType, NodeIndex};
+use super::{EdgeType, Incoming};
+
+use super::visit::GetAdjacencyMatrix;
+
+#[derive(Debug)]
+struct Vf2State<Ty, Ix> {
+ /// The current mapping M(s) of nodes from G0 → G1 and G1 → G0,
+ /// NodeIndex::end() for no mapping.
+ mapping: Vec<NodeIndex<Ix>>,
+ /// out[i] is non-zero if i is in either M_0(s) or Tout_0(s)
+ /// These are all the next vertices that are not mapped yet, but
+ /// have an outgoing edge from the mapping.
+ out: Vec<usize>,
+ /// ins[i] is non-zero if i is in either M_0(s) or Tin_0(s)
+ /// These are all the incoming vertices, those not mapped yet, but
+ /// have an edge from them into the mapping.
+ /// Unused if graph is undirected -- it's identical with out in that case.
+ ins: Vec<usize>,
+ out_size: usize,
+ ins_size: usize,
+ adjacency_matrix: FixedBitSet,
+ generation: usize,
+ _etype: marker::PhantomData<Ty>,
+}
+
+impl<Ty, Ix> Vf2State<Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ pub fn new<N, E>(g: &Graph<N, E, Ty, Ix>) -> Self {
+ let c0 = g.node_count();
+ let mut state = Vf2State {
+ mapping: Vec::with_capacity(c0),
+ out: Vec::with_capacity(c0),
+ ins: Vec::with_capacity(c0 * (g.is_directed() as usize)),
+ out_size: 0,
+ ins_size: 0,
+ adjacency_matrix: g.adjacency_matrix(),
+ generation: 0,
+ _etype: marker::PhantomData,
+ };
+ for _ in 0..c0 {
+ state.mapping.push(NodeIndex::end());
+ state.out.push(0);
+ if Ty::is_directed() {
+ state.ins.push(0);
+ }
+ }
+ state
+ }
+
+ /// Return **true** if we have a complete mapping
+ pub fn is_complete(&self) -> bool {
+ self.generation == self.mapping.len()
+ }
+
+ /// Add mapping **from** <-> **to** to the state.
+ pub fn push_mapping<N, E>(
+ &mut self,
+ from: NodeIndex<Ix>,
+ to: NodeIndex<Ix>,
+ g: &Graph<N, E, Ty, Ix>,
+ ) {
+ self.generation += 1;
+ let s = self.generation;
+ self.mapping[from.index()] = to;
+ // update T0 & T1 ins/outs
+ // T0out: Node in G0 not in M0 but successor of a node in M0.
+ // st.out[0]: Node either in M0 or successor of M0
+ for ix in g.neighbors(from) {
+ if self.out[ix.index()] == 0 {
+ self.out[ix.index()] = s;
+ self.out_size += 1;
+ }
+ }
+ if g.is_directed() {
+ for ix in g.neighbors_directed(from, Incoming) {
+ if self.ins[ix.index()] == 0 {
+ self.ins[ix.index()] = s;
+ self.ins_size += 1;
+ }
+ }
+ }
+ }
+
+ /// Restore the state to before the last added mapping
+ pub fn pop_mapping<N, E>(&mut self, from: NodeIndex<Ix>, g: &Graph<N, E, Ty, Ix>) {
+ let s = self.generation;
+ self.generation -= 1;
+
+ // undo (n, m) mapping
+ self.mapping[from.index()] = NodeIndex::end();
+
+ // unmark in ins and outs
+ for ix in g.neighbors(from) {
+ if self.out[ix.index()] == s {
+ self.out[ix.index()] = 0;
+ self.out_size -= 1;
+ }
+ }
+ if g.is_directed() {
+ for ix in g.neighbors_directed(from, Incoming) {
+ if self.ins[ix.index()] == s {
+ self.ins[ix.index()] = 0;
+ self.ins_size -= 1;
+ }
+ }
+ }
+ }
+
+ /// Find the next (least) node in the Tout set.
+ pub fn next_out_index(&self, from_index: usize) -> Option<usize> {
+ self.out[from_index..]
+ .iter()
+ .enumerate()
+ .find(move |&(index, elt)| {
+ *elt > 0 && self.mapping[from_index + index] == NodeIndex::end()
+ })
+ .map(|(index, _)| index)
+ }
+
+ /// Find the next (least) node in the Tin set.
+ pub fn next_in_index(&self, from_index: usize) -> Option<usize> {
+ if !Ty::is_directed() {
+ return None;
+ }
+ self.ins[from_index..]
+ .iter()
+ .enumerate()
+ .find(move |&(index, elt)| {
+ *elt > 0 && self.mapping[from_index + index] == NodeIndex::end()
+ })
+ .map(|(index, _)| index)
+ }
+
+ /// Find the next (least) node in the N - M set.
+ pub fn next_rest_index(&self, from_index: usize) -> Option<usize> {
+ self.mapping[from_index..]
+ .iter()
+ .enumerate()
+ .find(|&(_, elt)| *elt == NodeIndex::end())
+ .map(|(index, _)| index)
+ }
+}
+
+/// [Graph] Return `true` if the graphs `g0` and `g1` are isomorphic.
+///
+/// Using the VF2 algorithm, only matching graph syntactically (graph
+/// structure).
+///
+/// The graphs should not be multigraphs.
+///
+/// **Reference**
+///
+/// * Luigi P. Cordella, Pasquale Foggia, Carlo Sansone, Mario Vento;
+/// *A (Sub)Graph Isomorphism Algorithm for Matching Large Graphs*
+pub fn is_isomorphic<N, E, Ty, Ix>(g0: &Graph<N, E, Ty, Ix>, g1: &Graph<N, E, Ty, Ix>) -> bool
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ if g0.node_count() != g1.node_count() || g0.edge_count() != g1.edge_count() {
+ return false;
+ }
+
+ let mut st = [Vf2State::new(g0), Vf2State::new(g1)];
+ try_match(&mut st, g0, g1, &mut NoSemanticMatch, &mut NoSemanticMatch).unwrap_or(false)
+}
+
+/// [Graph] Return `true` if the graphs `g0` and `g1` are isomorphic.
+///
+/// Using the VF2 algorithm, examining both syntactic and semantic
+/// graph isomorphism (graph structure and matching node and edge weights).
+///
+/// The graphs should not be multigraphs.
+pub fn is_isomorphic_matching<N, E, Ty, Ix, F, G>(
+ g0: &Graph<N, E, Ty, Ix>,
+ g1: &Graph<N, E, Ty, Ix>,
+ mut node_match: F,
+ mut edge_match: G,
+) -> bool
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+ F: FnMut(&N, &N) -> bool,
+ G: FnMut(&E, &E) -> bool,
+{
+ if g0.node_count() != g1.node_count() || g0.edge_count() != g1.edge_count() {
+ return false;
+ }
+
+ let mut st = [Vf2State::new(g0), Vf2State::new(g1)];
+ try_match(&mut st, g0, g1, &mut node_match, &mut edge_match).unwrap_or(false)
+}
+
+trait SemanticMatcher<T> {
+ fn enabled() -> bool;
+ fn eq(&mut self, _: &T, _: &T) -> bool;
+}
+
+struct NoSemanticMatch;
+
+impl<T> SemanticMatcher<T> for NoSemanticMatch {
+ #[inline]
+ fn enabled() -> bool {
+ false
+ }
+ #[inline]
+ fn eq(&mut self, _: &T, _: &T) -> bool {
+ true
+ }
+}
+
+impl<T, F> SemanticMatcher<T> for F
+where
+ F: FnMut(&T, &T) -> bool,
+{
+ #[inline]
+ fn enabled() -> bool {
+ true
+ }
+ #[inline]
+ fn eq(&mut self, a: &T, b: &T) -> bool {
+ self(a, b)
+ }
+}
+
+/// Return Some(bool) if isomorphism is decided, else None.
+fn try_match<N, E, Ty, Ix, F, G>(
+ mut st: &mut [Vf2State<Ty, Ix>; 2],
+ g0: &Graph<N, E, Ty, Ix>,
+ g1: &Graph<N, E, Ty, Ix>,
+ node_match: &mut F,
+ edge_match: &mut G,
+) -> Option<bool>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+ F: SemanticMatcher<N>,
+ G: SemanticMatcher<E>,
+{
+ if st[0].is_complete() {
+ return Some(true);
+ }
+ let g = [g0, g1];
+ let graph_indices = 0..2;
+ let end = NodeIndex::end();
+
+ // A "depth first" search of a valid mapping from graph 1 to graph 2
+
+ // F(s, n, m) -- evaluate state s and add mapping n <-> m
+
+ // Find least T1out node (in st.out[1] but not in M[1])
+ #[derive(Copy, Clone, PartialEq, Debug)]
+ enum OpenList {
+ Out,
+ In,
+ Other,
+ }
+
+ #[derive(Clone, PartialEq, Debug)]
+ enum Frame<N: marker::Copy> {
+ Outer,
+ Inner { nodes: [N; 2], open_list: OpenList },
+ Unwind { nodes: [N; 2], open_list: OpenList },
+ }
+
+ let next_candidate =
+ |st: &mut [Vf2State<Ty, Ix>; 2]| -> Option<(NodeIndex<Ix>, NodeIndex<Ix>, OpenList)> {
+ let mut to_index;
+ let mut from_index = None;
+ let mut open_list = OpenList::Out;
+ // Try the out list
+ to_index = st[1].next_out_index(0);
+
+ if to_index.is_some() {
+ from_index = st[0].next_out_index(0);
+ open_list = OpenList::Out;
+ }
+ // Try the in list
+ if to_index.is_none() || from_index.is_none() {
+ to_index = st[1].next_in_index(0);
+
+ if to_index.is_some() {
+ from_index = st[0].next_in_index(0);
+ open_list = OpenList::In;
+ }
+ }
+ // Try the other list -- disconnected graph
+ if to_index.is_none() || from_index.is_none() {
+ to_index = st[1].next_rest_index(0);
+ if to_index.is_some() {
+ from_index = st[0].next_rest_index(0);
+ open_list = OpenList::Other;
+ }
+ }
+ match (from_index, to_index) {
+ (Some(n), Some(m)) => Some((NodeIndex::new(n), NodeIndex::new(m), open_list)),
+ // No more candidates
+ _ => None,
+ }
+ };
+ let next_from_ix = |st: &mut [Vf2State<Ty, Ix>; 2],
+ nx: NodeIndex<Ix>,
+ open_list: OpenList|
+ -> Option<NodeIndex<Ix>> {
+ // Find the next node index to try on the `from` side of the mapping
+ let start = nx.index() + 1;
+ let cand0 = match open_list {
+ OpenList::Out => st[0].next_out_index(start),
+ OpenList::In => st[0].next_in_index(start),
+ OpenList::Other => st[0].next_rest_index(start),
+ }
+ .map(|c| c + start); // compensate for start offset.
+ match cand0 {
+ None => None, // no more candidates
+ Some(ix) => {
+ debug_assert!(ix >= start);
+ Some(NodeIndex::new(ix))
+ }
+ }
+ };
+ //fn pop_state(nodes: [NodeIndex<Ix>; 2]) {
+ let pop_state = |st: &mut [Vf2State<Ty, Ix>; 2], nodes: [NodeIndex<Ix>; 2]| {
+ // Restore state.
+ for j in graph_indices.clone() {
+ st[j].pop_mapping(nodes[j], g[j]);
+ }
+ };
+ //fn push_state(nodes: [NodeIndex<Ix>; 2]) {
+ let push_state = |st: &mut [Vf2State<Ty, Ix>; 2], nodes: [NodeIndex<Ix>; 2]| {
+ // Add mapping nx <-> mx to the state
+ for j in graph_indices.clone() {
+ st[j].push_mapping(nodes[j], nodes[1 - j], g[j]);
+ }
+ };
+ //fn is_feasible(nodes: [NodeIndex<Ix>; 2]) -> bool {
+ let mut is_feasible = |st: &mut [Vf2State<Ty, Ix>; 2], nodes: [NodeIndex<Ix>; 2]| -> bool {
+ // Check syntactic feasibility of mapping by ensuring adjacencies
+ // of nx map to adjacencies of mx.
+ //
+ // nx == map to => mx
+ //
+ // R_succ
+ //
+ // Check that every neighbor of nx is mapped to a neighbor of mx,
+ // then check the reverse, from mx to nx. Check that they have the same
+ // count of edges.
+ //
+ // Note: We want to check the lookahead measures here if we can,
+ // R_out: Equal for G0, G1: Card(Succ(G, n) ^ Tout); for both Succ and Pred
+ // R_in: Same with Tin
+ // R_new: Equal for G0, G1: Ñ n Pred(G, n); both Succ and Pred,
+ // Ñ is G0 - M - Tin - Tout
+ // last attempt to add these did not speed up any of the testcases
+ let mut succ_count = [0, 0];
+ for j in graph_indices.clone() {
+ for n_neigh in g[j].neighbors(nodes[j]) {
+ succ_count[j] += 1;
+ // handle the self loop case; it's not in the mapping (yet)
+ let m_neigh = if nodes[j] != n_neigh {
+ st[j].mapping[n_neigh.index()]
+ } else {
+ nodes[1 - j]
+ };
+ if m_neigh == end {
+ continue;
+ }
+ let has_edge =
+ g[1 - j].is_adjacent(&st[1 - j].adjacency_matrix, nodes[1 - j], m_neigh);
+ if !has_edge {
+ return false;
+ }
+ }
+ }
+ if succ_count[0] != succ_count[1] {
+ return false;
+ }
+ // R_pred
+ if g[0].is_directed() {
+ let mut pred_count = [0, 0];
+ for j in graph_indices.clone() {
+ for n_neigh in g[j].neighbors_directed(nodes[j], Incoming) {
+ pred_count[j] += 1;
+ // the self loop case is handled in outgoing
+ let m_neigh = st[j].mapping[n_neigh.index()];
+ if m_neigh == end {
+ continue;
+ }
+ let has_edge =
+ g[1 - j].is_adjacent(&st[1 - j].adjacency_matrix, m_neigh, nodes[1 - j]);
+ if !has_edge {
+ return false;
+ }
+ }
+ }
+ if pred_count[0] != pred_count[1] {
+ return false;
+ }
+ }
+ // semantic feasibility: compare associated data for nodes
+ if F::enabled() && !node_match.eq(&g[0][nodes[0]], &g[1][nodes[1]]) {
+ return false;
+ }
+ // semantic feasibility: compare associated data for edges
+ if G::enabled() {
+ // outgoing edges
+ for j in graph_indices.clone() {
+ let mut edges = g[j].neighbors(nodes[j]).detach();
+ while let Some((n_edge, n_neigh)) = edges.next(g[j]) {
+ // handle the self loop case; it's not in the mapping (yet)
+ let m_neigh = if nodes[j] != n_neigh {
+ st[j].mapping[n_neigh.index()]
+ } else {
+ nodes[1 - j]
+ };
+ if m_neigh == end {
+ continue;
+ }
+ match g[1 - j].find_edge(nodes[1 - j], m_neigh) {
+ Some(m_edge) => {
+ if !edge_match.eq(&g[j][n_edge], &g[1 - j][m_edge]) {
+ return false;
+ }
+ }
+ None => unreachable!(), // covered by syntactic check
+ }
+ }
+ }
+ // incoming edges
+ if g[0].is_directed() {
+ for j in graph_indices.clone() {
+ let mut edges = g[j].neighbors_directed(nodes[j], Incoming).detach();
+ while let Some((n_edge, n_neigh)) = edges.next(g[j]) {
+ // the self loop case is handled in outgoing
+ let m_neigh = st[j].mapping[n_neigh.index()];
+ if m_neigh == end {
+ continue;
+ }
+ match g[1 - j].find_edge(m_neigh, nodes[1 - j]) {
+ Some(m_edge) => {
+ if !edge_match.eq(&g[j][n_edge], &g[1 - j][m_edge]) {
+ return false;
+ }
+ }
+ None => unreachable!(), // covered by syntactic check
+ }
+ }
+ }
+ }
+ }
+ true
+ };
+ let mut stack: Vec<Frame<NodeIndex<Ix>>> = vec![Frame::Outer];
+
+ while let Some(frame) = stack.pop() {
+ match frame {
+ Frame::Unwind {
+ nodes,
+ open_list: ol,
+ } => {
+ pop_state(&mut st, nodes);
+
+ match next_from_ix(&mut st, nodes[0], ol) {
+ None => continue,
+ Some(nx) => {
+ let f = Frame::Inner {
+ nodes: [nx, nodes[1]],
+ open_list: ol,
+ };
+ stack.push(f);
+ }
+ }
+ }
+ Frame::Outer => match next_candidate(&mut st) {
+ None => continue,
+ Some((nx, mx, ol)) => {
+ let f = Frame::Inner {
+ nodes: [nx, mx],
+ open_list: ol,
+ };
+ stack.push(f);
+ }
+ },
+ Frame::Inner {
+ nodes,
+ open_list: ol,
+ } => {
+ if is_feasible(&mut st, nodes) {
+ push_state(&mut st, nodes);
+ if st[0].is_complete() {
+ return Some(true);
+ }
+ // Check cardinalities of Tin, Tout sets
+ if st[0].out_size == st[1].out_size && st[0].ins_size == st[1].ins_size {
+ let f0 = Frame::Unwind {
+ nodes,
+ open_list: ol,
+ };
+ stack.push(f0);
+ stack.push(Frame::Outer);
+ continue;
+ }
+ pop_state(&mut st, nodes);
+ }
+ match next_from_ix(&mut st, nodes[0], ol) {
+ None => continue,
+ Some(nx) => {
+ let f = Frame::Inner {
+ nodes: [nx, nodes[1]],
+ open_list: ol,
+ };
+ stack.push(f);
+ }
+ }
+ }
+ }
+ }
+ None
+}
diff --git a/vendor/petgraph/src/iter_format.rs b/vendor/petgraph/src/iter_format.rs
new file mode 100644
index 000000000..f6ffd6aff
--- /dev/null
+++ b/vendor/petgraph/src/iter_format.rs
@@ -0,0 +1,102 @@
+//! Formatting utils
+
+use std::cell::RefCell;
+use std::fmt;
+
+/// Format the iterator like a map
+pub struct DebugMap<F>(pub F);
+
+impl<'a, F, I, K, V> fmt::Debug for DebugMap<F>
+where
+ F: Fn() -> I,
+ I: IntoIterator<Item = (K, V)>,
+ K: fmt::Debug,
+ V: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_map().entries((self.0)()).finish()
+ }
+}
+
+/// Avoid "pretty" debug
+pub struct NoPretty<T>(pub T);
+
+impl<T> fmt::Debug for NoPretty<T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:?}", self.0)
+ }
+}
+
+/// Format all iterator elements lazily, separated by `sep`.
+///
+/// The format value can only be formatted once, after that the iterator is
+/// exhausted.
+///
+/// See [`.format()`](../trait.Itertools.html#method.format)
+/// for more information.
+#[derive(Clone)]
+pub struct Format<'a, I> {
+ sep: &'a str,
+ /// Format uses interior mutability because Display::fmt takes &self.
+ inner: RefCell<Option<I>>,
+}
+
+pub trait IterFormatExt: Iterator {
+ fn format(self, separator: &str) -> Format<Self>
+ where
+ Self: Sized,
+ {
+ Format {
+ sep: separator,
+ inner: RefCell::new(Some(self)),
+ }
+ }
+}
+
+impl<I> IterFormatExt for I where I: Iterator {}
+
+impl<'a, I> Format<'a, I>
+where
+ I: Iterator,
+{
+ fn format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result
+ where
+ F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,
+ {
+ let mut iter = match self.inner.borrow_mut().take() {
+ Some(t) => t,
+ None => panic!("Format: was already formatted once"),
+ };
+
+ if let Some(fst) = iter.next() {
+ cb(&fst, f)?;
+ for elt in iter {
+ if !self.sep.is_empty() {
+ f.write_str(self.sep)?;
+ }
+ cb(&elt, f)?;
+ }
+ }
+ Ok(())
+ }
+}
+
+macro_rules! impl_format {
+ ($($fmt_trait:ident)*) => {
+ $(
+ impl<'a, I> fmt::$fmt_trait for Format<'a, I>
+ where I: Iterator,
+ I::Item: fmt::$fmt_trait,
+ {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.format(f, fmt::$fmt_trait::fmt)
+ }
+ }
+ )*
+ }
+}
+
+impl_format!(Debug);
diff --git a/vendor/petgraph/src/iter_utils.rs b/vendor/petgraph/src/iter_utils.rs
new file mode 100644
index 000000000..587af84c6
--- /dev/null
+++ b/vendor/petgraph/src/iter_utils.rs
@@ -0,0 +1,32 @@
+pub trait IterUtilsExt: Iterator {
+ /// Return the first element that maps to `Some(_)`, or None if the iterator
+ /// was exhausted.
+ fn ex_find_map<F, R>(&mut self, mut f: F) -> Option<R>
+ where
+ F: FnMut(Self::Item) -> Option<R>,
+ {
+ for elt in self {
+ if let result @ Some(_) = f(elt) {
+ return result;
+ }
+ }
+ None
+ }
+
+ /// Return the last element from the back that maps to `Some(_)`, or
+ /// None if the iterator was exhausted.
+ fn ex_rfind_map<F, R>(&mut self, mut f: F) -> Option<R>
+ where
+ F: FnMut(Self::Item) -> Option<R>,
+ Self: DoubleEndedIterator,
+ {
+ while let Some(elt) = self.next_back() {
+ if let result @ Some(_) = f(elt) {
+ return result;
+ }
+ }
+ None
+ }
+}
+
+impl<I> IterUtilsExt for I where I: Iterator {}
diff --git a/vendor/petgraph/src/lib.rs b/vendor/petgraph/src/lib.rs
new file mode 100644
index 000000000..1dc36f786
--- /dev/null
+++ b/vendor/petgraph/src/lib.rs
@@ -0,0 +1,308 @@
+//! `petgraph` is a graph data structure library.
+//!
+//! Graphs are collections of nodes, and edges between nodes. `petgraph`
+//! provides several [graph types](index.html#graph-types) (each differing in the
+//! tradeoffs taken in their internal representation),
+//! [algorithms](./algo/index.html#functions) on those graphs, and functionality to
+//! [output graphs](./doc/petgraph/dot/struct.Dot.html) in
+//! [`graphviz`](https://www.graphviz.org/) format. Both nodes and edges
+//! can have arbitrary associated data, and edges may be either directed or undirected.
+//!
+//! # Example
+//!
+//! ```rust
+//! use petgraph::graph::{NodeIndex, UnGraph};
+//! use petgraph::algo::{dijkstra, min_spanning_tree};
+//! use petgraph::data::FromElements;
+//! use petgraph::dot::{Dot, Config};
+//!
+//! // Create an undirected graph with `i32` nodes and edges with `()` associated data.
+//! let g = UnGraph::<i32, ()>::from_edges(&[
+//! (1, 2), (2, 3), (3, 4),
+//! (1, 4)]);
+//!
+//! // Find the shortest path from `1` to `4` using `1` as the cost for every edge.
+//! let node_map = dijkstra(&g, 1.into(), Some(4.into()), |_| 1);
+//! assert_eq!(&1i32, node_map.get(&NodeIndex::new(4)).unwrap());
+//!
+//! // Get the minimum spanning tree of the graph as a new graph, and check that
+//! // one edge was trimmed.
+//! let mst = UnGraph::<_, _>::from_elements(min_spanning_tree(&g));
+//! assert_eq!(g.raw_edges().len() - 1, mst.raw_edges().len());
+//!
+//! // Output the tree to `graphviz` `DOT` format
+//! println!("{:?}", Dot::with_config(&mst, &[Config::EdgeNoLabel]));
+//! // graph {
+//! // 0 [label="\"0\""]
+//! // 1 [label="\"0\""]
+//! // 2 [label="\"0\""]
+//! // 3 [label="\"0\""]
+//! // 1 -- 2
+//! // 3 -- 4
+//! // 2 -- 3
+//! // }
+//! ```
+//!
+//! # Graph types
+//!
+//! * [`Graph`](./graph/struct.Graph.html) -
+//! An adjacency list graph with arbitrary associated data.
+//! * [`StableGraph`](./stable_graph/struct.StableGraph.html) -
+//! Similar to `Graph`, but it keeps indices stable across removals.
+//! * [`GraphMap`](./graphmap/struct.GraphMap.html) -
+//! An adjacency list graph backed by a hash table. The node identifiers are the keys
+//! into the table.
+//! * [`MatrixGraph`](./matrix_graph/struct.MatrixGraph.html) -
+//! An adjacency matrix graph.
+//! * [`CSR`](./csr/struct.Csr.html) -
+//! A sparse adjacency matrix graph with arbitrary associated data.
+//!
+//! ### Generic parameters
+//!
+//! Each graph type is generic over a handful of parameters. All graphs share 3 common
+//! parameters, `N`, `E`, and `Ty`. This is a broad overview of what those are. Each
+//! type's documentation will have finer detail on these parameters.
+//!
+//! `N` & `E` are called *weights* in this implementation, and are associated with
+//! nodes and edges respectively. They can generally be of arbitrary type, and don't have to
+//! be what you might conventionally consider weight-like. For example, using `&str` for `N`
+//! will work. Many algorithms that require costs let you provide a cost function that
+//! translates your `N` and `E` weights into costs appropriate to the algorithm. Some graph
+//! types and choices do impose bounds on `N` or `E`.
+//! [`min_spanning_tree`](./algo/fn.min_spanning_tree.html) for example requires edge weights that
+//! implement [`PartialOrd`](https://doc.rust-lang.org/stable/core/cmp/trait.PartialOrd.html).
+//! [`GraphMap`](./graphmap/struct.GraphMap.html) requires node weights that can serve as hash
+//! map keys, since that graph type does not create standalone node indices.
+//!
+//! `Ty` controls whether edges are [`Directed`](./petgraph/enum.Directed.html) or
+//! [`Undirected`](./petgraph/enum.Unirected.html).
+//!
+//! `Ix` appears on graph types that use indices. It is exposed so you can control
+//! the size of node and edge indices, and therefore the memory footprint of your graphs.
+//! Allowed values are `u8`, `u16`, `u32`, and `usize`, with `u32` being the default.
+//!
+//! ### Shorthand types
+//!
+//! Each graph type vends a few shorthand type definitions that name some specific
+//! generic choices. For example, [`DiGraph<_, _>`](./graph/type.DiGraph.html) is shorthand
+//! for [`Graph<_, _, Directed>`](graph/struct.Graph.html).
+//! [`UnMatrix<_, _>`](./matrix_graph/type.UnMatrix.html) is shorthand for
+//! [`MatrixGraph<_, _, Undirected>`](./matrix_graph/struct.MatrixGraph.html). Each graph type's
+//! module documentation lists the available shorthand types.
+//!
+//! # Crate features
+//!
+//! * **serde-1** -
+//! Defaults off. Enables serialization for ``Graph, StableGraph`` using
+//! [`serde 1.0`](https://crates.io/crates/serde). May require a more recent version
+//! of Rust than petgraph alone.
+//! * **graphmap** -
+//! Defaults on. Enables [`GraphMap`](./graphmap/struct.GraphMap.html).
+//! * **stable_graph** -
+//! Defaults on. Enables [`StableGraph`](./stable_graph/struct.StableGraph.html).
+//! * **matrix_graph** -
+//! Defaults on. Enables [`MatrixGraph`](./matrix_graph/struct.MatrixGraph.html).
+//!
+#![doc(html_root_url = "https://docs.rs/petgraph/0.4/")]
+
+extern crate fixedbitset;
+#[cfg(feature = "graphmap")]
+extern crate indexmap;
+
+#[cfg(feature = "serde-1")]
+extern crate serde;
+#[cfg(feature = "serde-1")]
+#[macro_use]
+extern crate serde_derive;
+
+#[cfg(all(feature = "serde-1", test))]
+extern crate itertools;
+
+#[doc(no_inline)]
+pub use crate::graph::Graph;
+
+pub use crate::Direction::{Incoming, Outgoing};
+
+#[macro_use]
+mod macros;
+mod scored;
+
+// these modules define trait-implementing macros
+#[macro_use]
+pub mod visit;
+#[macro_use]
+pub mod data;
+
+pub mod algo;
+mod astar;
+pub mod csr;
+mod dijkstra;
+pub mod dot;
+#[cfg(feature = "generate")]
+pub mod generate;
+mod graph_impl;
+#[cfg(feature = "graphmap")]
+pub mod graphmap;
+mod isomorphism;
+mod iter_format;
+mod iter_utils;
+#[cfg(feature = "matrix_graph")]
+pub mod matrix_graph;
+#[cfg(feature = "quickcheck")]
+mod quickcheck;
+#[cfg(feature = "serde-1")]
+mod serde_utils;
+mod simple_paths;
+mod traits_graph;
+pub mod unionfind;
+mod util;
+
+pub mod prelude;
+
+/// `Graph<N, E, Ty, Ix>` is a graph datastructure using an adjacency list representation.
+pub mod graph {
+ pub use crate::graph_impl::{
+ edge_index, node_index, DefaultIx, DiGraph, Edge, EdgeIndex, EdgeIndices, EdgeReference,
+ EdgeReferences, EdgeWeightsMut, Edges, EdgesConnecting, Externals, Frozen, Graph,
+ GraphIndex, IndexType, Neighbors, Node, NodeIndex, NodeIndices, NodeReferences,
+ NodeWeightsMut, UnGraph, WalkNeighbors,
+ };
+}
+
+#[cfg(feature = "stable_graph")]
+pub use crate::graph_impl::stable_graph;
+
+macro_rules! copyclone {
+ ($name:ident) => {
+ impl Clone for $name {
+ #[inline]
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ };
+}
+
+// Index into the NodeIndex and EdgeIndex arrays
+/// Edge direction.
+#[derive(Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
+#[repr(usize)]
+pub enum Direction {
+ /// An `Outgoing` edge is an outward edge *from* the current node.
+ Outgoing = 0,
+ /// An `Incoming` edge is an inbound edge *to* the current node.
+ Incoming = 1,
+}
+
+copyclone!(Direction);
+
+impl Direction {
+ /// Return the opposite `Direction`.
+ #[inline]
+ pub fn opposite(self) -> Direction {
+ match self {
+ Outgoing => Incoming,
+ Incoming => Outgoing,
+ }
+ }
+
+ /// Return `0` for `Outgoing` and `1` for `Incoming`.
+ #[inline]
+ pub fn index(self) -> usize {
+ (self as usize) & 0x1
+ }
+}
+
+#[doc(hidden)]
+pub use crate::Direction as EdgeDirection;
+
+/// Marker type for a directed graph.
+#[derive(Copy, Debug)]
+pub enum Directed {}
+copyclone!(Directed);
+
+/// Marker type for an undirected graph.
+#[derive(Copy, Debug)]
+pub enum Undirected {}
+copyclone!(Undirected);
+
+/// A graph's edge type determines whether it has directed edges or not.
+pub trait EdgeType {
+ fn is_directed() -> bool;
+}
+
+impl EdgeType for Directed {
+ #[inline]
+ fn is_directed() -> bool {
+ true
+ }
+}
+
+impl EdgeType for Undirected {
+ #[inline]
+ fn is_directed() -> bool {
+ false
+ }
+}
+
+/// Convert an element like `(i, j)` or `(i, j, w)` into
+/// a triple of source, target, edge weight.
+///
+/// For `Graph::from_edges` and `GraphMap::from_edges`.
+pub trait IntoWeightedEdge<E> {
+ type NodeId;
+ fn into_weighted_edge(self) -> (Self::NodeId, Self::NodeId, E);
+}
+
+impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix)
+where
+ E: Default,
+{
+ type NodeId = Ix;
+
+ fn into_weighted_edge(self) -> (Ix, Ix, E) {
+ let (s, t) = self;
+ (s, t, E::default())
+ }
+}
+
+impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix, E) {
+ type NodeId = Ix;
+ fn into_weighted_edge(self) -> (Ix, Ix, E) {
+ self
+ }
+}
+
+impl<'a, Ix, E> IntoWeightedEdge<E> for (Ix, Ix, &'a E)
+where
+ E: Clone,
+{
+ type NodeId = Ix;
+ fn into_weighted_edge(self) -> (Ix, Ix, E) {
+ let (a, b, c) = self;
+ (a, b, c.clone())
+ }
+}
+
+impl<'a, Ix, E> IntoWeightedEdge<E> for &'a (Ix, Ix)
+where
+ Ix: Copy,
+ E: Default,
+{
+ type NodeId = Ix;
+ fn into_weighted_edge(self) -> (Ix, Ix, E) {
+ let (s, t) = *self;
+ (s, t, E::default())
+ }
+}
+
+impl<'a, Ix, E> IntoWeightedEdge<E> for &'a (Ix, Ix, E)
+where
+ Ix: Copy,
+ E: Clone,
+{
+ type NodeId = Ix;
+ fn into_weighted_edge(self) -> (Ix, Ix, E) {
+ self.clone()
+ }
+}
diff --git a/vendor/petgraph/src/macros.rs b/vendor/petgraph/src/macros.rs
new file mode 100644
index 000000000..0d86ad13d
--- /dev/null
+++ b/vendor/petgraph/src/macros.rs
@@ -0,0 +1,11 @@
+macro_rules! clone_fields {
+ ($name:ident, $($field:ident),+ $(,)*) => (
+ fn clone(&self) -> Self {
+ $name {
+ $(
+ $field : self . $field .clone()
+ ),*
+ }
+ }
+ );
+}
diff --git a/vendor/petgraph/src/matrix_graph.rs b/vendor/petgraph/src/matrix_graph.rs
new file mode 100644
index 000000000..2fdbfc137
--- /dev/null
+++ b/vendor/petgraph/src/matrix_graph.rs
@@ -0,0 +1,1671 @@
+//! `MatrixGraph<N, E, Ty, NullN, NullE, Ix>` is a graph datastructure backed by an adjacency matrix.
+
+use std::marker::PhantomData;
+use std::ops::{Index, IndexMut};
+
+use std::cmp;
+use std::mem;
+
+use indexmap::IndexSet;
+
+use fixedbitset::FixedBitSet;
+
+use crate::{Directed, Direction, EdgeType, IntoWeightedEdge, Outgoing, Undirected};
+
+use crate::graph::NodeIndex as GraphNodeIndex;
+
+use crate::visit::{
+ Data, GetAdjacencyMatrix, GraphBase, GraphProp, IntoEdgeReferences, IntoEdges, IntoNeighbors,
+ IntoNeighborsDirected, IntoNodeIdentifiers, IntoNodeReferences, NodeCompactIndexable,
+ NodeCount, NodeIndexable, Visitable,
+};
+
+use crate::data::Build;
+
+pub use crate::graph::IndexType;
+
+// The following types are used to control the max size of the adjacency matrix. Since the maximum
+// size of the matrix vector's is the square of the maximum number of nodes, the number of nodes
+// should be reasonably picked.
+type DefaultIx = u16;
+
+/// Node identifier.
+pub type NodeIndex<Ix = DefaultIx> = GraphNodeIndex<Ix>;
+
+mod private {
+ pub trait Sealed {}
+
+ impl<T> Sealed for super::NotZero<T> {}
+ impl<T> Sealed for Option<T> {}
+}
+
+/// Wrapper trait for an `Option`, allowing user-defined structs to be input as containers when
+/// defining a null element.
+///
+/// Note: this trait is currently *sealed* and cannot be implemented for types outside this crate.
+pub trait Nullable: Default + Into<Option<<Self as Nullable>::Wrapped>> + private::Sealed {
+ #[doc(hidden)]
+ type Wrapped;
+
+ #[doc(hidden)]
+ fn new(value: Self::Wrapped) -> Self;
+
+ #[doc(hidden)]
+ fn as_ref(&self) -> Option<&Self::Wrapped>;
+
+ #[doc(hidden)]
+ fn as_mut(&mut self) -> Option<&mut Self::Wrapped>;
+
+ #[doc(hidden)]
+ fn is_null(&self) -> bool {
+ self.as_ref().is_none()
+ }
+}
+
+impl<T> Nullable for Option<T> {
+ type Wrapped = T;
+
+ fn new(value: T) -> Self {
+ Some(value)
+ }
+
+ fn as_ref(&self) -> Option<&Self::Wrapped> {
+ self.as_ref()
+ }
+
+ fn as_mut(&mut self) -> Option<&mut Self::Wrapped> {
+ self.as_mut()
+ }
+}
+
+/// `NotZero` is used to optimize the memory usage of edge weights `E` in a
+/// [`MatrixGraph`](struct.MatrixGraph.html), replacing the default `Option<E>` sentinel.
+///
+/// Pre-requisite: edge weight should implement [`Zero`](trait.Zero.html).
+///
+/// Note that if you're already using the standard non-zero types (such as `NonZeroU32`), you don't
+/// have to use this wrapper and can leave the default `Null` type argument.
+pub struct NotZero<T>(T);
+
+impl<T: Zero> Default for NotZero<T> {
+ fn default() -> Self {
+ NotZero(T::zero())
+ }
+}
+
+impl<T: Zero> Nullable for NotZero<T> {
+ type Wrapped = T;
+
+ fn new(value: T) -> Self {
+ assert!(!value.is_zero());
+ NotZero(value)
+ }
+
+ // implemented here for optimization purposes
+ fn is_null(&self) -> bool {
+ self.0.is_zero()
+ }
+
+ fn as_ref(&self) -> Option<&Self::Wrapped> {
+ if !self.is_null() {
+ Some(&self.0)
+ } else {
+ None
+ }
+ }
+
+ fn as_mut(&mut self) -> Option<&mut Self::Wrapped> {
+ if !self.is_null() {
+ Some(&mut self.0)
+ } else {
+ None
+ }
+ }
+}
+
+impl<T: Zero> Into<Option<T>> for NotZero<T> {
+ fn into(self) -> Option<T> {
+ if !self.is_null() {
+ Some(self.0)
+ } else {
+ None
+ }
+ }
+}
+
+/// Base trait for types that can be wrapped in a [`NotZero`](struct.NotZero.html).
+///
+/// Implementors must provide a singleton object that will be used to mark empty edges in a
+/// [`MatrixGraph`](struct.MatrixGraph.html).
+///
+/// Note that this trait is already implemented for the base numeric types.
+pub trait Zero {
+ /// Return the singleton object which can be used as a sentinel value.
+ fn zero() -> Self;
+
+ /// Return true if `self` is equal to the sentinel value.
+ fn is_zero(&self) -> bool;
+}
+
+macro_rules! not_zero_impl {
+ ($t:ty,$z:expr) => {
+ impl Zero for $t {
+ fn zero() -> Self {
+ $z as $t
+ }
+
+ fn is_zero(&self) -> bool {
+ self == &Self::zero()
+ }
+ }
+ };
+}
+
+macro_rules! not_zero_impls {
+ ($($t:ty),*) => {
+ $(
+ not_zero_impl!($t, 0);
+ )*
+ }
+}
+
+not_zero_impls!(u8, u16, u32, u64, usize);
+not_zero_impls!(i8, i16, i32, i64, isize);
+not_zero_impls!(f32, f64);
+
+/// Short version of `NodeIndex::new` (with Ix = `DefaultIx`)
+#[inline]
+pub fn node_index(ax: usize) -> NodeIndex {
+ NodeIndex::new(ax)
+}
+
+/// `MatrixGraph<N, E, Ty, Null>` is a graph datastructure using an adjacency matrix
+/// representation.
+///
+/// `MatrixGraph` is parameterized over:
+///
+/// - Associated data `N` for nodes and `E` for edges, called *weights*.
+/// The associated data can be of arbitrary type.
+/// - Edge type `Ty` that determines whether the graph edges are directed or undirected.
+/// - Nullable type `Null`, which denotes the edges' presence (defaults to `Option<E>`). You may
+/// specify [`NotZero<E>`](struct.NotZero.html) if you want to use a sentinel value (such as 0)
+/// to mark the absence of an edge.
+/// - Index type `Ix` that sets the maximum size for the graph (defaults to `DefaultIx`).
+///
+/// The graph uses **O(|V^2|)** space, with fast edge insertion & amortized node insertion, as well
+/// as efficient graph search and graph algorithms on dense graphs.
+///
+/// This graph is backed by a flattened 2D array. For undirected graphs, only the lower triangular
+/// matrix is stored. Since the backing array stores edge weights, it is recommended to box large
+/// edge weights.
+#[derive(Clone)]
+pub struct MatrixGraph<N, E, Ty = Directed, Null: Nullable<Wrapped = E> = Option<E>, Ix = DefaultIx>
+{
+ node_adjacencies: Vec<Null>,
+ node_capacity: usize,
+ nodes: IdStorage<N>,
+ nb_edges: usize,
+ ty: PhantomData<Ty>,
+ ix: PhantomData<Ix>,
+}
+
+/// A `MatrixGraph` with directed edges.
+pub type DiMatrix<N, E, Null = Option<E>, Ix = DefaultIx> = MatrixGraph<N, E, Directed, Null, Ix>;
+
+/// A `MatrixGraph` with undirected edges.
+pub type UnMatrix<N, E, Null = Option<E>, Ix = DefaultIx> = MatrixGraph<N, E, Undirected, Null, Ix>;
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType>
+ MatrixGraph<N, E, Ty, Null, Ix>
+{
+ /// Create a new `MatrixGraph` with estimated capacity for nodes.
+ pub fn with_capacity(node_capacity: usize) -> Self {
+ let mut m = Self {
+ node_adjacencies: vec![],
+ node_capacity: 0,
+ nodes: IdStorage::with_capacity(node_capacity),
+ nb_edges: 0,
+ ty: PhantomData,
+ ix: PhantomData,
+ };
+
+ debug_assert!(node_capacity <= <Ix as IndexType>::max().index());
+ m.extend_capacity_for_node(NodeIndex::new(node_capacity));
+
+ m
+ }
+
+ #[inline]
+ fn to_edge_position(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> usize {
+ to_linearized_matrix_position::<Ty>(a.index(), b.index(), self.node_capacity)
+ }
+
+ /// Remove all nodes and edges.
+ pub fn clear(&mut self) {
+ for edge in self.node_adjacencies.iter_mut() {
+ *edge = Default::default();
+ }
+ self.nodes.clear();
+ self.nb_edges = 0;
+ }
+
+ /// Return the number of nodes (vertices) in the graph.
+ ///
+ /// Computes in **O(1)** time.
+ #[inline]
+ pub fn node_count(&self) -> usize {
+ self.nodes.len()
+ }
+
+ /// Return the number of edges in the graph.
+ ///
+ /// Computes in **O(1)** time.
+ #[inline]
+ pub fn edge_count(&self) -> usize {
+ self.nb_edges
+ }
+
+ /// Return whether the graph has directed edges or not.
+ #[inline]
+ pub fn is_directed(&self) -> bool {
+ Ty::is_directed()
+ }
+
+ /// Add a node (also called vertex) with associated data `weight` to the graph.
+ ///
+ /// Computes in **O(1)** time.
+ ///
+ /// Return the index of the new node.
+ ///
+ /// **Panics** if the MatrixGraph is at the maximum number of nodes for its index type.
+ pub fn add_node(&mut self, weight: N) -> NodeIndex<Ix> {
+ NodeIndex::new(self.nodes.add(weight))
+ }
+
+ /// Remove `a` from the graph.
+ ///
+ /// Computes in **O(V)** time, due to the removal of edges with other nodes.
+ ///
+ /// **Panics** if the node `a` does not exist.
+ pub fn remove_node(&mut self, a: NodeIndex<Ix>) -> N {
+ for id in self.nodes.iter_ids() {
+ let position = self.to_edge_position(a, NodeIndex::new(id));
+ self.node_adjacencies[position] = Default::default();
+
+ if Ty::is_directed() {
+ let position = self.to_edge_position(NodeIndex::new(id), a);
+ self.node_adjacencies[position] = Default::default();
+ }
+ }
+
+ self.nodes.remove(a.index())
+ }
+
+ #[inline]
+ fn extend_capacity_for_node(&mut self, min_node: NodeIndex<Ix>) {
+ self.node_capacity = extend_linearized_matrix::<Ty, _>(
+ &mut self.node_adjacencies,
+ self.node_capacity,
+ min_node.index(),
+ );
+ }
+
+ #[inline]
+ fn extend_capacity_for_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) {
+ let min_node = cmp::max(a, b);
+ if min_node.index() >= self.node_capacity {
+ self.extend_capacity_for_node(min_node);
+ }
+ }
+
+ /// Update the edge from `a` to `b` to the graph, with its associated data `weight`.
+ ///
+ /// Return the previous data, if any.
+ ///
+ /// Computes in **O(1)** time, best case.
+ /// Computes in **O(|V|^2)** time, worst case (matrix needs to be re-allocated).
+ ///
+ /// **Panics** if any of the nodes don't exist.
+ pub fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> Option<E> {
+ self.extend_capacity_for_edge(a, b);
+
+ let p = self.to_edge_position(a, b);
+ let old_weight = mem::replace(&mut self.node_adjacencies[p], Null::new(weight));
+ if old_weight.is_null() {
+ self.nb_edges += 1;
+ }
+ old_weight.into()
+ }
+
+ /// Add an edge from `a` to `b` to the graph, with its associated
+ /// data `weight`.
+ ///
+ /// Return the index of the new edge.
+ ///
+ /// Computes in **O(1)** time, best case.
+ /// Computes in **O(|V|^2)** time, worst case (matrix needs to be re-allocated).
+ ///
+ /// **Panics** if any of the nodes don't exist.
+ /// **Panics** if an edge already exists from `a` to `b`.
+ ///
+ /// **Note:** `MatrixGraph` does not allow adding parallel (“duplicate”) edges. If you want to avoid
+ /// this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
+ pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) {
+ let old_edge_id = self.update_edge(a, b, weight);
+ assert!(old_edge_id.is_none());
+ }
+
+ /// Remove the edge from `a` to `b` to the graph.
+ ///
+ /// **Panics** if any of the nodes don't exist.
+ /// **Panics** if no edge exists between `a` and `b`.
+ pub fn remove_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> E {
+ let p = self.to_edge_position(a, b);
+ let old_weight = mem::replace(&mut self.node_adjacencies[p], Default::default())
+ .into()
+ .unwrap();
+ let old_weight: Option<_> = old_weight.into();
+ self.nb_edges -= 1;
+ old_weight.unwrap()
+ }
+
+ /// Return true if there is an edge between `a` and `b`.
+ ///
+ /// **Panics** if any of the nodes don't exist.
+ pub fn has_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
+ let p = self.to_edge_position(a, b);
+ !self.node_adjacencies[p].is_null()
+ }
+
+ /// Access the weight for node `a`.
+ ///
+ /// Also available with indexing syntax: `&graph[a]`.
+ ///
+ /// **Panics** if the node doesn't exist.
+ pub fn node_weight(&self, a: NodeIndex<Ix>) -> &N {
+ &self.nodes[a.index()]
+ }
+
+ /// Access the weight for node `a`, mutably.
+ ///
+ /// Also available with indexing syntax: `&mut graph[a]`.
+ ///
+ /// **Panics** if the node doesn't exist.
+ pub fn node_weight_mut(&mut self, a: NodeIndex<Ix>) -> &mut N {
+ &mut self.nodes[a.index()]
+ }
+
+ /// Access the weight for edge `e`.
+ ///
+ /// Also available with indexing syntax: `&graph[e]`.
+ ///
+ /// **Panics** if no edge exists between `a` and `b`.
+ pub fn edge_weight(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> &E {
+ let p = self.to_edge_position(a, b);
+ self.node_adjacencies[p].as_ref().unwrap()
+ }
+
+ /// Access the weight for edge `e`, mutably.
+ ///
+ /// Also available with indexing syntax: `&mut graph[e]`.
+ ///
+ /// **Panics** if no edge exists between `a` and `b`.
+ pub fn edge_weight_mut(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> &mut E {
+ let p = self.to_edge_position(a, b);
+ self.node_adjacencies[p].as_mut().unwrap()
+ }
+
+ /// Return an iterator of all nodes with an edge starting from `a`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges from or to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is [`NodeIndex<Ix>`](../graph/struct.NodeIndex.html).
+ pub fn neighbors(&self, a: NodeIndex<Ix>) -> Neighbors<Ty, Null, Ix> {
+ Neighbors(Edges::on_columns(
+ a.index(),
+ &self.node_adjacencies,
+ self.node_capacity,
+ ))
+ }
+
+ /// Return an iterator of all edges of `a`.
+ ///
+ /// - `Directed`: Outgoing edges from `a`.
+ /// - `Undirected`: All edges connected to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is [`Edges<E, Ix>`](../graph/struct.Edges.html).
+ pub fn edges(&self, a: NodeIndex<Ix>) -> Edges<Ty, Null, Ix> {
+ Edges::on_columns(a.index(), &self.node_adjacencies, self.node_capacity)
+ }
+
+ /// Create a new `MatrixGraph` from an iterable of edges.
+ ///
+ /// Node weights `N` are set to default values.
+ /// Edge weights `E` may either be specified in the list,
+ /// or they are filled with default values.
+ ///
+ /// Nodes are inserted automatically to match the edges.
+ ///
+ /// ```
+ /// use petgraph::matrix_graph::MatrixGraph;
+ ///
+ /// let gr = MatrixGraph::<(), i32>::from_edges(&[
+ /// (0, 1), (0, 2), (0, 3),
+ /// (1, 2), (1, 3),
+ /// (2, 3),
+ /// ]);
+ /// ```
+ pub fn from_edges<I>(iterable: I) -> Self
+ where
+ I: IntoIterator,
+ I::Item: IntoWeightedEdge<E>,
+ <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
+ N: Default,
+ {
+ let mut g = Self::default();
+ g.extend_with_edges(iterable);
+ g
+ }
+
+ /// Extend the graph from an iterable of edges.
+ ///
+ /// Node weights `N` are set to default values.
+ /// Edge weights `E` may either be specified in the list,
+ /// or they are filled with default values.
+ ///
+ /// Nodes are inserted automatically to match the edges.
+ pub fn extend_with_edges<I>(&mut self, iterable: I)
+ where
+ I: IntoIterator,
+ I::Item: IntoWeightedEdge<E>,
+ <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
+ N: Default,
+ {
+ for elt in iterable {
+ let (source, target, weight) = elt.into_weighted_edge();
+ let (source, target) = (source.into(), target.into());
+ let nx = cmp::max(source, target);
+ while nx.index() >= self.node_count() {
+ self.add_node(N::default());
+ }
+ self.add_edge(source, target, weight);
+ }
+ }
+}
+
+impl<N, E, Null: Nullable<Wrapped = E>, Ix: IndexType> MatrixGraph<N, E, Directed, Null, Ix> {
+ /// Return an iterator of all neighbors that have an edge between them and
+ /// `a`, in the specified direction.
+ /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*.
+ ///
+ /// - `Outgoing`: All edges from `a`.
+ /// - `Incoming`: All edges to `a`.
+ ///
+ /// Produces an empty iterator if the node doesn't exist.<br>
+ /// Iterator element type is [`NodeIndex<Ix>`](../graph/struct.NodeIndex.html).
+ pub fn neighbors_directed(
+ &self,
+ a: NodeIndex<Ix>,
+ d: Direction,
+ ) -> Neighbors<Directed, Null, Ix> {
+ if d == Outgoing {
+ self.neighbors(a)
+ } else {
+ Neighbors(Edges::on_rows(
+ a.index(),
+ &self.node_adjacencies,
+ self.node_capacity,
+ ))
+ }
+ }
+
+ /// Return an iterator of all edges of `a`, in the specified direction.
+ ///
+ /// - `Outgoing`: All edges from `a`.
+ /// - `Incoming`: All edges to `a`.
+ ///
+ /// Produces an empty iterator if the node `a` doesn't exist.<br>
+ /// Iterator element type is [`EdgeReference<E, Ix>`](../graph/struct.EdgeReference.html).
+ pub fn edges_directed(&self, a: NodeIndex<Ix>, d: Direction) -> Edges<Directed, Null, Ix> {
+ if d == Outgoing {
+ self.edges(a)
+ } else {
+ Edges::on_rows(a.index(), &self.node_adjacencies, self.node_capacity)
+ }
+ }
+}
+
+/// Iterator over the node identifiers of a graph.
+///
+/// Created from a call to [`.node_identifiers()`][1] on a [`MatrixGraph`][2].
+///
+/// [1]: ../visit/trait.IntoNodeIdentifiers.html#tymethod.node_identifiers
+/// [2]: struct.MatrixGraph.html
+pub struct NodeIdentifiers<'a, Ix> {
+ iter: IdIterator<'a>,
+ ix: PhantomData<Ix>,
+}
+
+impl<'a, Ix: IndexType> NodeIdentifiers<'a, Ix> {
+ fn new(iter: IdIterator<'a>) -> Self {
+ Self {
+ iter,
+ ix: PhantomData,
+ }
+ }
+}
+
+impl<'a, Ix: IndexType> Iterator for NodeIdentifiers<'a, Ix> {
+ type Item = NodeIndex<Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(NodeIndex::new)
+ }
+}
+
+/// Iterator over all nodes of a graph.
+///
+/// Created from a call to [`.node_references()`][1] on a [`MatrixGraph`][2].
+///
+/// [1]: ../visit/trait.IntoNodeReferences.html#tymethod.node_references
+/// [2]: struct.MatrixGraph.html
+pub struct NodeReferences<'a, N: 'a, Ix> {
+ nodes: &'a IdStorage<N>,
+ iter: IdIterator<'a>,
+ ix: PhantomData<Ix>,
+}
+
+impl<'a, N: 'a, Ix> NodeReferences<'a, N, Ix> {
+ fn new(nodes: &'a IdStorage<N>) -> Self {
+ NodeReferences {
+ nodes,
+ iter: nodes.iter_ids(),
+ ix: PhantomData,
+ }
+ }
+}
+
+impl<'a, N: 'a, Ix: IndexType> Iterator for NodeReferences<'a, N, Ix> {
+ type Item = (NodeIndex<Ix>, &'a N);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter
+ .next()
+ .map(|i| (NodeIndex::new(i), &self.nodes[i]))
+ }
+}
+
+/// Iterator over all edges of a graph.
+///
+/// Created from a call to [`.edge_references()`][1] on a [`MatrixGraph`][2].
+///
+/// [1]: ../visit/trait.IntoEdgeReferences.html#tymethod.edge_references
+/// [2]: struct.MatrixGraph.html
+pub struct EdgeReferences<'a, Ty: EdgeType, Null: 'a + Nullable, Ix> {
+ row: usize,
+ column: usize,
+ node_adjacencies: &'a [Null],
+ node_capacity: usize,
+ ty: PhantomData<Ty>,
+ ix: PhantomData<Ix>,
+}
+
+impl<'a, Ty: EdgeType, Null: 'a + Nullable, Ix> EdgeReferences<'a, Ty, Null, Ix> {
+ fn new(node_adjacencies: &'a [Null], node_capacity: usize) -> Self {
+ EdgeReferences {
+ row: 0,
+ column: 0,
+ node_adjacencies,
+ node_capacity,
+ ty: PhantomData,
+ ix: PhantomData,
+ }
+ }
+}
+
+impl<'a, Ty: EdgeType, Null: Nullable, Ix: IndexType> Iterator
+ for EdgeReferences<'a, Ty, Null, Ix>
+{
+ type Item = (NodeIndex<Ix>, NodeIndex<Ix>, &'a Null::Wrapped);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ let (row, column) = (self.row, self.column);
+ if row >= self.node_capacity {
+ return None;
+ }
+
+ // By default, advance the column. Reset and advance the row if the column overflows.
+ //
+ // Note that for undirected graphs, we don't want to yield the same edge twice,
+ // therefore the maximum column length should be the index new after the row index.
+ self.column += 1;
+ let max_column_len = if !Ty::is_directed() {
+ row + 1
+ } else {
+ self.node_capacity
+ };
+ if self.column >= max_column_len {
+ self.column = 0;
+ self.row += 1;
+ }
+
+ let p = to_linearized_matrix_position::<Ty>(row, column, self.node_capacity);
+ if let Some(e) = self.node_adjacencies[p].as_ref() {
+ return Some((NodeIndex::new(row), NodeIndex::new(column), e));
+ }
+ }
+ }
+}
+
+/// Iterator over the neighbors of a node.
+///
+/// Iterator element type is `NodeIndex<Ix>`.
+///
+/// Created with [`.neighbors()`][1], [`.neighbors_directed()`][2].
+///
+/// [1]: struct.MatrixGraph.html#method.neighbors
+/// [2]: struct.MatrixGraph.html#method.neighbors_directed
+pub struct Neighbors<'a, Ty: EdgeType, Null: 'a + Nullable, Ix>(Edges<'a, Ty, Null, Ix>);
+
+impl<'a, Ty: EdgeType, Null: Nullable, Ix: IndexType> Iterator for Neighbors<'a, Ty, Null, Ix> {
+ type Item = NodeIndex<Ix>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().map(|(_, b, _)| b)
+ }
+}
+
+enum NeighborIterDirection {
+ Rows,
+ Columns,
+}
+
+/// Iterator over the edges of from or to a node
+///
+/// Created with [`.edges()`][1], [`.edges_directed()`][2].
+///
+/// [1]: struct.MatrixGraph.html#method.edges
+/// [2]: struct.MatrixGraph.html#method.edges_directed
+pub struct Edges<'a, Ty: EdgeType, Null: 'a + Nullable, Ix> {
+ iter_direction: NeighborIterDirection,
+ node_adjacencies: &'a [Null],
+ node_capacity: usize,
+ row: usize,
+ column: usize,
+ ty: PhantomData<Ty>,
+ ix: PhantomData<Ix>,
+}
+
+impl<'a, Ty: EdgeType, Null: 'a + Nullable, Ix> Edges<'a, Ty, Null, Ix> {
+ fn on_columns(row: usize, node_adjacencies: &'a [Null], node_capacity: usize) -> Self {
+ Edges {
+ iter_direction: NeighborIterDirection::Columns,
+ node_adjacencies,
+ node_capacity,
+ row,
+ column: 0,
+ ty: PhantomData,
+ ix: PhantomData,
+ }
+ }
+
+ fn on_rows(column: usize, node_adjacencies: &'a [Null], node_capacity: usize) -> Self {
+ Edges {
+ iter_direction: NeighborIterDirection::Rows,
+ node_adjacencies,
+ node_capacity,
+ row: 0,
+ column,
+ ty: PhantomData,
+ ix: PhantomData,
+ }
+ }
+}
+
+impl<'a, Ty: EdgeType, Null: Nullable, Ix: IndexType> Iterator for Edges<'a, Ty, Null, Ix> {
+ type Item = (NodeIndex<Ix>, NodeIndex<Ix>, &'a Null::Wrapped);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ use self::NeighborIterDirection::*;
+
+ loop {
+ let (row, column) = (self.row, self.column);
+ if row >= self.node_capacity || column >= self.node_capacity {
+ return None;
+ }
+
+ match self.iter_direction {
+ Rows => self.row += 1,
+ Columns => self.column += 1,
+ }
+
+ let p = to_linearized_matrix_position::<Ty>(row, column, self.node_capacity);
+ if let Some(e) = self.node_adjacencies[p].as_ref() {
+ let (a, b) = match self.iter_direction {
+ Rows => (column, row),
+ Columns => (row, column),
+ };
+
+ return Some((NodeIndex::new(a), NodeIndex::new(b), e));
+ }
+ }
+ }
+}
+
+#[inline]
+fn to_linearized_matrix_position<Ty: EdgeType>(row: usize, column: usize, width: usize) -> usize {
+ if Ty::is_directed() {
+ to_flat_square_matrix_position(row, column, width)
+ } else {
+ to_lower_triangular_matrix_position(row, column)
+ }
+}
+
+#[inline]
+fn extend_linearized_matrix<Ty: EdgeType, T: Default>(
+ node_adjacencies: &mut Vec<T>,
+ old_node_capacity: usize,
+ min_node_capacity: usize,
+) -> usize {
+ if Ty::is_directed() {
+ extend_flat_square_matrix(node_adjacencies, old_node_capacity, min_node_capacity)
+ } else {
+ extend_lower_triangular_matrix(node_adjacencies, min_node_capacity)
+ }
+}
+
+#[inline]
+fn to_flat_square_matrix_position(row: usize, column: usize, width: usize) -> usize {
+ row * width + column
+}
+
+#[inline]
+fn extend_flat_square_matrix<T: Default>(
+ node_adjacencies: &mut Vec<T>,
+ old_node_capacity: usize,
+ min_node_capacity: usize,
+) -> usize {
+ let min_node_capacity = (min_node_capacity + 1).next_power_of_two();
+
+ // Optimization: when resizing the matrix this way we skip the first few grows to make
+ // small matrices a bit faster to work with.
+ const MIN_CAPACITY: usize = 4;
+ let new_node_capacity = cmp::max(min_node_capacity, MIN_CAPACITY);
+
+ let mut new_node_adjacencies = vec![];
+ ensure_len(&mut new_node_adjacencies, new_node_capacity.pow(2));
+
+ for c in 0..old_node_capacity {
+ let pos = c * old_node_capacity;
+ let new_pos = c * new_node_capacity;
+
+ let mut old = &mut node_adjacencies[pos..pos + old_node_capacity];
+ let mut new = &mut new_node_adjacencies[new_pos..new_pos + old_node_capacity];
+
+ mem::swap(&mut old, &mut new);
+ }
+
+ mem::swap(node_adjacencies, &mut new_node_adjacencies);
+
+ new_node_capacity
+}
+
+#[inline]
+fn to_lower_triangular_matrix_position(row: usize, column: usize) -> usize {
+ let (row, column) = if row > column {
+ (row, column)
+ } else {
+ (column, row)
+ };
+ (row * (row + 1)) / 2 + column
+}
+
+#[inline]
+fn extend_lower_triangular_matrix<T: Default>(
+ node_adjacencies: &mut Vec<T>,
+ new_node_capacity: usize,
+) -> usize {
+ let max_pos = to_lower_triangular_matrix_position(new_node_capacity, new_node_capacity);
+ ensure_len(node_adjacencies, max_pos + 1);
+ new_node_capacity + 1
+}
+
+/// Grow a Vec by appending the type's default value until the `size` is reached.
+fn ensure_len<T: Default>(v: &mut Vec<T>, size: usize) {
+ if let Some(n) = size.checked_sub(v.len()) {
+ v.reserve(n);
+ for _ in 0..n {
+ v.push(T::default());
+ }
+ }
+}
+
+#[derive(Clone)]
+struct IdStorage<T> {
+ elements: Vec<Option<T>>,
+ upper_bound: usize,
+ removed_ids: IndexSet<usize>,
+}
+
+impl<T> IdStorage<T> {
+ fn with_capacity(capacity: usize) -> Self {
+ IdStorage {
+ elements: Vec::with_capacity(capacity),
+ upper_bound: 0,
+ removed_ids: IndexSet::new(),
+ }
+ }
+
+ fn add(&mut self, element: T) -> usize {
+ let id = if let Some(id) = self.removed_ids.pop() {
+ id
+ } else {
+ let id = self.upper_bound;
+ self.upper_bound += 1;
+
+ ensure_len(&mut self.elements, id + 1);
+
+ id
+ };
+
+ self.elements[id] = Some(element);
+
+ id
+ }
+
+ fn remove(&mut self, id: usize) -> T {
+ let data = self.elements[id].take().unwrap();
+ if self.upper_bound - id == 1 {
+ self.upper_bound -= 1;
+ } else {
+ self.removed_ids.insert(id);
+ }
+ data
+ }
+
+ fn clear(&mut self) {
+ self.upper_bound = 0;
+ self.elements.clear();
+ self.removed_ids.clear();
+ }
+
+ #[inline]
+ fn len(&self) -> usize {
+ self.upper_bound - self.removed_ids.len()
+ }
+
+ fn iter_ids(&self) -> IdIterator {
+ IdIterator {
+ upper_bound: self.upper_bound,
+ removed_ids: &self.removed_ids,
+ current: None,
+ }
+ }
+}
+
+impl<T> Index<usize> for IdStorage<T> {
+ type Output = T;
+ fn index(&self, index: usize) -> &T {
+ self.elements[index].as_ref().unwrap()
+ }
+}
+
+impl<T> IndexMut<usize> for IdStorage<T> {
+ fn index_mut(&mut self, index: usize) -> &mut T {
+ self.elements[index].as_mut().unwrap()
+ }
+}
+
+struct IdIterator<'a> {
+ upper_bound: usize,
+ removed_ids: &'a IndexSet<usize>,
+ current: Option<usize>,
+}
+
+impl<'a> Iterator for IdIterator<'a> {
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ // initialize / advance
+ let current = {
+ if self.current.is_none() {
+ self.current = Some(0);
+ self.current.as_mut().unwrap()
+ } else {
+ let current = self.current.as_mut().unwrap();
+ *current += 1;
+ current
+ }
+ };
+
+ // skip removed ids
+ while self.removed_ids.contains(current) && *current < self.upper_bound {
+ *current += 1;
+ }
+
+ if *current < self.upper_bound {
+ Some(*current)
+ } else {
+ None
+ }
+ }
+}
+
+/// Create a new empty `MatrixGraph`.
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Default
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ fn default() -> Self {
+ Self::with_capacity(0)
+ }
+}
+
+impl<N, E> MatrixGraph<N, E, Directed> {
+ /// Create a new `MatrixGraph` with directed edges.
+ ///
+ /// This is a convenience method. Use `MatrixGraph::with_capacity` or `MatrixGraph::default` for
+ /// a constructor that is generic in all the type parameters of `MatrixGraph`.
+ pub fn new() -> Self {
+ MatrixGraph::default()
+ }
+}
+
+impl<N, E> MatrixGraph<N, E, Undirected> {
+ /// Create a new `MatrixGraph` with undirected edges.
+ ///
+ /// This is a convenience method. Use `MatrixGraph::with_capacity` or `MatrixGraph::default` for
+ /// a constructor that is generic in all the type parameters of `MatrixGraph`.
+ pub fn new_undirected() -> Self {
+ MatrixGraph::default()
+ }
+}
+
+/// Index the `MatrixGraph` by `NodeIndex` to access node weights.
+///
+/// **Panics** if the node doesn't exist.
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Index<NodeIndex<Ix>>
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type Output = N;
+
+ fn index(&self, ax: NodeIndex<Ix>) -> &N {
+ self.node_weight(ax)
+ }
+}
+
+/// Index the `MatrixGraph` by `NodeIndex` to access node weights.
+///
+/// **Panics** if the node doesn't exist.
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IndexMut<NodeIndex<Ix>>
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ fn index_mut(&mut self, ax: NodeIndex<Ix>) -> &mut N {
+ self.node_weight_mut(ax)
+ }
+}
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> NodeCount
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ fn node_count(&self) -> usize {
+ MatrixGraph::node_count(self)
+ }
+}
+
+/// Index the `MatrixGraph` by `NodeIndex` pair to access edge weights.
+///
+/// Also available with indexing syntax: `&graph[e]`.
+///
+/// **Panics** if no edge exists between `a` and `b`.
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType>
+ Index<(NodeIndex<Ix>, NodeIndex<Ix>)> for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type Output = E;
+
+ fn index(&self, (ax, bx): (NodeIndex<Ix>, NodeIndex<Ix>)) -> &E {
+ self.edge_weight(ax, bx)
+ }
+}
+
+/// Index the `MatrixGraph` by `NodeIndex` pair to access edge weights.
+///
+/// Also available with indexing syntax: `&mut graph[e]`.
+///
+/// **Panics** if no edge exists between `a` and `b`.
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType>
+ IndexMut<(NodeIndex<Ix>, NodeIndex<Ix>)> for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ fn index_mut(&mut self, (ax, bx): (NodeIndex<Ix>, NodeIndex<Ix>)) -> &mut E {
+ self.edge_weight_mut(ax, bx)
+ }
+}
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> GetAdjacencyMatrix
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type AdjMatrix = ();
+
+ fn adjacency_matrix(&self) -> Self::AdjMatrix {}
+
+ fn is_adjacent(&self, _: &Self::AdjMatrix, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
+ MatrixGraph::has_edge(self, a, b)
+ }
+}
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Visitable
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ 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());
+ }
+}
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> GraphBase
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type NodeId = NodeIndex<Ix>;
+ type EdgeId = (NodeIndex<Ix>, NodeIndex<Ix>);
+}
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> GraphProp
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type EdgeType = Ty;
+}
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Data
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type NodeWeight = N;
+ type EdgeWeight = E;
+}
+
+impl<'a, N, E: 'a, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoNodeIdentifiers
+ for &'a MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type NodeIdentifiers = NodeIdentifiers<'a, Ix>;
+
+ fn node_identifiers(self) -> Self::NodeIdentifiers {
+ NodeIdentifiers::new(self.nodes.iter_ids())
+ }
+}
+
+impl<'a, N, E: 'a, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoNeighbors
+ for &'a MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type Neighbors = Neighbors<'a, Ty, Null, Ix>;
+
+ fn neighbors(self, a: NodeIndex<Ix>) -> Self::Neighbors {
+ MatrixGraph::neighbors(self, a)
+ }
+}
+
+impl<'a, N, E: 'a, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoNeighborsDirected
+ for &'a MatrixGraph<N, E, Directed, Null, Ix>
+{
+ type NeighborsDirected = Neighbors<'a, Directed, Null, Ix>;
+
+ fn neighbors_directed(self, a: NodeIndex<Ix>, d: Direction) -> Self::NeighborsDirected {
+ MatrixGraph::neighbors_directed(self, a, d)
+ }
+}
+
+impl<'a, N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoNodeReferences
+ for &'a MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type NodeRef = (NodeIndex<Ix>, &'a N);
+ type NodeReferences = NodeReferences<'a, N, Ix>;
+ fn node_references(self) -> Self::NodeReferences {
+ NodeReferences::new(&self.nodes)
+ }
+}
+
+impl<'a, N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoEdgeReferences
+ for &'a MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type EdgeRef = (NodeIndex<Ix>, NodeIndex<Ix>, &'a E);
+ type EdgeReferences = EdgeReferences<'a, Ty, Null, Ix>;
+ fn edge_references(self) -> Self::EdgeReferences {
+ EdgeReferences::new(&self.node_adjacencies, self.node_capacity)
+ }
+}
+
+impl<'a, N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoEdges
+ for &'a MatrixGraph<N, E, Ty, Null, Ix>
+{
+ type Edges = Edges<'a, Ty, Null, Ix>;
+ fn edges(self, a: Self::NodeId) -> Self::Edges {
+ MatrixGraph::edges(self, a)
+ }
+}
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> NodeIndexable
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ 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: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> NodeCompactIndexable
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+}
+
+impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Build
+ for MatrixGraph<N, E, Ty, Null, Ix>
+{
+ fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
+ self.add_node(weight)
+ }
+
+ fn add_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Option<Self::EdgeId> {
+ if !self.has_edge(a, b) {
+ MatrixGraph::update_edge(self, a, b, weight);
+ Some((a, b))
+ } else {
+ None
+ }
+ }
+
+ fn update_edge(
+ &mut self,
+ a: Self::NodeId,
+ b: Self::NodeId,
+ weight: Self::EdgeWeight,
+ ) -> Self::EdgeId {
+ MatrixGraph::update_edge(self, a, b, weight);
+ (a, b)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::{Incoming, Outgoing};
+
+ #[test]
+ fn test_new() {
+ let g = MatrixGraph::<i32, i32>::new();
+ assert_eq!(g.node_count(), 0);
+ assert_eq!(g.edge_count(), 0);
+ }
+
+ #[test]
+ fn test_default() {
+ let g = MatrixGraph::<i32, i32>::default();
+ assert_eq!(g.node_count(), 0);
+ assert_eq!(g.edge_count(), 0);
+ }
+
+ #[test]
+ fn test_with_capacity() {
+ let g = MatrixGraph::<i32, i32>::with_capacity(10);
+ assert_eq!(g.node_count(), 0);
+ assert_eq!(g.edge_count(), 0);
+ }
+
+ #[test]
+ fn test_node_indexing() {
+ let mut g: MatrixGraph<char, ()> = MatrixGraph::new();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ assert_eq!(g.node_count(), 2);
+ assert_eq!(g.edge_count(), 0);
+ assert_eq!(g[a], 'a');
+ assert_eq!(g[b], 'b');
+ }
+
+ #[test]
+ fn test_remove_node() {
+ let mut g: MatrixGraph<char, ()> = MatrixGraph::new();
+ let a = g.add_node('a');
+
+ g.remove_node(a);
+
+ assert_eq!(g.node_count(), 0);
+ assert_eq!(g.edge_count(), 0);
+ }
+
+ #[test]
+ fn test_add_edge() {
+ let mut g = MatrixGraph::new();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ g.add_edge(a, b, ());
+ g.add_edge(b, c, ());
+ assert_eq!(g.node_count(), 3);
+ assert_eq!(g.edge_count(), 2);
+ }
+
+ #[test]
+ fn test_add_edge_with_weights() {
+ let mut g = MatrixGraph::new();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ g.add_edge(a, b, true);
+ g.add_edge(b, c, false);
+ assert_eq!(*g.edge_weight(a, b), true);
+ assert_eq!(*g.edge_weight(b, c), false);
+ }
+
+ #[test]
+ fn test_add_edge_with_weights_undirected() {
+ let mut g = MatrixGraph::new_undirected();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ let d = g.add_node('d');
+ g.add_edge(a, b, "ab");
+ g.add_edge(a, a, "aa");
+ g.add_edge(b, c, "bc");
+ g.add_edge(d, d, "dd");
+ assert_eq!(*g.edge_weight(a, b), "ab");
+ assert_eq!(*g.edge_weight(b, c), "bc");
+ }
+
+ /// Shorthand for `.collect::<Vec<_>>()`
+ trait IntoVec<T> {
+ fn into_vec(self) -> Vec<T>;
+ }
+
+ impl<It, T> IntoVec<T> for It
+ where
+ It: Iterator<Item = T>,
+ {
+ fn into_vec(self) -> Vec<T> {
+ self.collect()
+ }
+ }
+
+ #[test]
+ fn test_clear() {
+ let mut g = MatrixGraph::new();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ assert_eq!(g.node_count(), 3);
+
+ g.add_edge(a, b, ());
+ g.add_edge(b, c, ());
+ g.add_edge(c, a, ());
+ assert_eq!(g.edge_count(), 3);
+
+ g.clear();
+
+ assert_eq!(g.node_count(), 0);
+ assert_eq!(g.edge_count(), 0);
+
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ assert_eq!(g.node_count(), 3);
+ assert_eq!(g.edge_count(), 0);
+
+ assert_eq!(g.neighbors_directed(a, Incoming).into_vec(), vec![]);
+ assert_eq!(g.neighbors_directed(b, Incoming).into_vec(), vec![]);
+ assert_eq!(g.neighbors_directed(c, Incoming).into_vec(), vec![]);
+
+ assert_eq!(g.neighbors_directed(a, Outgoing).into_vec(), vec![]);
+ assert_eq!(g.neighbors_directed(b, Outgoing).into_vec(), vec![]);
+ assert_eq!(g.neighbors_directed(c, Outgoing).into_vec(), vec![]);
+ }
+
+ #[test]
+ fn test_clear_undirected() {
+ let mut g = MatrixGraph::new_undirected();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ assert_eq!(g.node_count(), 3);
+
+ g.add_edge(a, b, ());
+ g.add_edge(b, c, ());
+ g.add_edge(c, a, ());
+ assert_eq!(g.edge_count(), 3);
+
+ g.clear();
+
+ assert_eq!(g.node_count(), 0);
+ assert_eq!(g.edge_count(), 0);
+
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ assert_eq!(g.node_count(), 3);
+ assert_eq!(g.edge_count(), 0);
+
+ assert_eq!(g.neighbors(a).into_vec(), vec![]);
+ assert_eq!(g.neighbors(b).into_vec(), vec![]);
+ assert_eq!(g.neighbors(c).into_vec(), vec![]);
+ }
+
+ /// Helper trait for always sorting before testing.
+ trait IntoSortedVec<T> {
+ fn into_sorted_vec(self) -> Vec<T>;
+ }
+
+ impl<It, T> IntoSortedVec<T> for It
+ where
+ It: Iterator<Item = T>,
+ T: Ord,
+ {
+ fn into_sorted_vec(self) -> Vec<T> {
+ let mut v: Vec<T> = self.collect();
+ v.sort();
+ v
+ }
+ }
+
+ /// Helper macro for always sorting before testing.
+ macro_rules! sorted_vec {
+ ($($x:expr),*) => {
+ {
+ let mut v = vec![$($x,)*];
+ v.sort();
+ v
+ }
+ }
+ }
+
+ #[test]
+ fn test_neighbors() {
+ let mut g = MatrixGraph::new();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ g.add_edge(a, b, ());
+ g.add_edge(a, c, ());
+
+ let a_neighbors = g.neighbors(a).into_sorted_vec();
+ assert_eq!(a_neighbors, sorted_vec![b, c]);
+
+ let b_neighbors = g.neighbors(b).into_sorted_vec();
+ assert_eq!(b_neighbors, vec![]);
+
+ let c_neighbors = g.neighbors(c).into_sorted_vec();
+ assert_eq!(c_neighbors, vec![]);
+ }
+
+ #[test]
+ fn test_neighbors_undirected() {
+ let mut g = MatrixGraph::new_undirected();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ g.add_edge(a, b, ());
+ g.add_edge(a, c, ());
+
+ let a_neighbors = g.neighbors(a).into_sorted_vec();
+ assert_eq!(a_neighbors, sorted_vec![b, c]);
+
+ let b_neighbors = g.neighbors(b).into_sorted_vec();
+ assert_eq!(b_neighbors, sorted_vec![a]);
+
+ let c_neighbors = g.neighbors(c).into_sorted_vec();
+ assert_eq!(c_neighbors, sorted_vec![a]);
+ }
+
+ #[test]
+ fn test_remove_node_and_edges() {
+ let mut g = MatrixGraph::new();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ g.add_edge(a, b, ());
+ g.add_edge(b, c, ());
+ g.add_edge(c, a, ());
+
+ // removing b should break the `a -> b` and `b -> c` edges
+ g.remove_node(b);
+
+ assert_eq!(g.node_count(), 2);
+
+ let a_neighbors = g.neighbors(a).into_sorted_vec();
+ assert_eq!(a_neighbors, vec![]);
+
+ let c_neighbors = g.neighbors(c).into_sorted_vec();
+ assert_eq!(c_neighbors, vec![a]);
+ }
+
+ #[test]
+ fn test_remove_node_and_edges_undirected() {
+ let mut g = UnMatrix::new_undirected();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ g.add_edge(a, b, ());
+ g.add_edge(b, c, ());
+ g.add_edge(c, a, ());
+
+ // removing a should break the `a - b` and `a - c` edges
+ g.remove_node(a);
+
+ assert_eq!(g.node_count(), 2);
+
+ let b_neighbors = g.neighbors(b).into_sorted_vec();
+ assert_eq!(b_neighbors, vec![c]);
+
+ let c_neighbors = g.neighbors(c).into_sorted_vec();
+ assert_eq!(c_neighbors, vec![b]);
+ }
+
+ #[test]
+ fn test_node_identifiers() {
+ let mut g = MatrixGraph::new();
+ let a = g.add_node('a');
+ let b = g.add_node('b');
+ let c = g.add_node('c');
+ let d = g.add_node('c');
+ g.add_edge(a, b, ());
+ g.add_edge(a, c, ());
+
+ let node_ids = g.node_identifiers().into_sorted_vec();
+ assert_eq!(node_ids, sorted_vec![a, b, c, d]);
+ }
+
+ #[test]
+ fn test_edges_directed() {
+ let g: MatrixGraph<char, bool> = MatrixGraph::from_edges(&[
+ (0, 5),
+ (0, 2),
+ (0, 3),
+ (0, 1),
+ (1, 3),
+ (2, 3),
+ (2, 4),
+ (4, 0),
+ (6, 6),
+ ]);
+
+ assert_eq!(g.edges_directed(node_index(0), Outgoing).count(), 4);
+ assert_eq!(g.edges_directed(node_index(1), Outgoing).count(), 1);
+ assert_eq!(g.edges_directed(node_index(2), Outgoing).count(), 2);
+ assert_eq!(g.edges_directed(node_index(3), Outgoing).count(), 0);
+ assert_eq!(g.edges_directed(node_index(4), Outgoing).count(), 1);
+ assert_eq!(g.edges_directed(node_index(5), Outgoing).count(), 0);
+ assert_eq!(g.edges_directed(node_index(6), Outgoing).count(), 1);
+
+ assert_eq!(g.edges_directed(node_index(0), Incoming).count(), 1);
+ assert_eq!(g.edges_directed(node_index(1), Incoming).count(), 1);
+ assert_eq!(g.edges_directed(node_index(2), Incoming).count(), 1);
+ assert_eq!(g.edges_directed(node_index(3), Incoming).count(), 3);
+ assert_eq!(g.edges_directed(node_index(4), Incoming).count(), 1);
+ assert_eq!(g.edges_directed(node_index(5), Incoming).count(), 1);
+ assert_eq!(g.edges_directed(node_index(6), Incoming).count(), 1);
+ }
+
+ #[test]
+ fn test_edges_undirected() {
+ let g: UnMatrix<char, bool> = UnMatrix::from_edges(&[
+ (0, 5),
+ (0, 2),
+ (0, 3),
+ (0, 1),
+ (1, 3),
+ (2, 3),
+ (2, 4),
+ (4, 0),
+ (6, 6),
+ ]);
+
+ assert_eq!(g.edges(node_index(0)).count(), 5);
+ assert_eq!(g.edges(node_index(1)).count(), 2);
+ assert_eq!(g.edges(node_index(2)).count(), 3);
+ assert_eq!(g.edges(node_index(3)).count(), 3);
+ assert_eq!(g.edges(node_index(4)).count(), 2);
+ assert_eq!(g.edges(node_index(5)).count(), 1);
+ assert_eq!(g.edges(node_index(6)).count(), 1);
+ }
+
+ #[test]
+ fn test_edges_of_absent_node_is_empty_iterator() {
+ let g: MatrixGraph<char, bool> = MatrixGraph::new();
+ assert_eq!(g.edges(node_index(0)).count(), 0);
+ }
+
+ #[test]
+ fn test_neighbors_of_absent_node_is_empty_iterator() {
+ let g: MatrixGraph<char, bool> = MatrixGraph::new();
+ assert_eq!(g.neighbors(node_index(0)).count(), 0);
+ }
+
+ #[test]
+ fn test_edge_references() {
+ let g: MatrixGraph<char, bool> = MatrixGraph::from_edges(&[
+ (0, 5),
+ (0, 2),
+ (0, 3),
+ (0, 1),
+ (1, 3),
+ (2, 3),
+ (2, 4),
+ (4, 0),
+ (6, 6),
+ ]);
+
+ assert_eq!(g.edge_references().count(), 9);
+ }
+
+ #[test]
+ fn test_edge_references_undirected() {
+ let g: UnMatrix<char, bool> = UnMatrix::from_edges(&[
+ (0, 5),
+ (0, 2),
+ (0, 3),
+ (0, 1),
+ (1, 3),
+ (2, 3),
+ (2, 4),
+ (4, 0),
+ (6, 6),
+ ]);
+
+ assert_eq!(g.edge_references().count(), 9);
+ }
+
+ #[test]
+ fn test_id_storage() {
+ use super::IdStorage;
+
+ let mut storage: IdStorage<char> = IdStorage::with_capacity(0);
+ let a = storage.add('a');
+ let b = storage.add('b');
+ let c = storage.add('c');
+
+ assert!(a < b && b < c);
+
+ // list IDs
+ assert_eq!(storage.iter_ids().into_vec(), vec![a, b, c]);
+
+ storage.remove(b);
+
+ // re-use of IDs
+ let bb = storage.add('B');
+ assert_eq!(b, bb);
+
+ // list IDs
+ assert_eq!(storage.iter_ids().into_vec(), vec![a, b, c]);
+ }
+
+ #[test]
+ fn test_not_zero() {
+ let mut g: MatrixGraph<(), i32, Directed, NotZero<i32>> = MatrixGraph::default();
+
+ let a = g.add_node(());
+ let b = g.add_node(());
+
+ assert!(!g.has_edge(a, b));
+ assert_eq!(g.edge_count(), 0);
+
+ g.add_edge(a, b, 12);
+
+ assert!(g.has_edge(a, b));
+ assert_eq!(g.edge_count(), 1);
+ assert_eq!(g.edge_weight(a, b), &12);
+
+ g.remove_edge(a, b);
+
+ assert!(!g.has_edge(a, b));
+ assert_eq!(g.edge_count(), 0);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_not_zero_asserted() {
+ let mut g: MatrixGraph<(), i32, Directed, NotZero<i32>> = MatrixGraph::default();
+
+ let a = g.add_node(());
+ let b = g.add_node(());
+
+ g.add_edge(a, b, 0); // this should trigger an assertion
+ }
+
+ #[test]
+ fn test_not_zero_float() {
+ let mut g: MatrixGraph<(), f32, Directed, NotZero<f32>> = MatrixGraph::default();
+
+ let a = g.add_node(());
+ let b = g.add_node(());
+
+ assert!(!g.has_edge(a, b));
+ assert_eq!(g.edge_count(), 0);
+
+ g.add_edge(a, b, 12.);
+
+ assert!(g.has_edge(a, b));
+ assert_eq!(g.edge_count(), 1);
+ assert_eq!(g.edge_weight(a, b), &12.);
+
+ g.remove_edge(a, b);
+
+ assert!(!g.has_edge(a, b));
+ assert_eq!(g.edge_count(), 0);
+ }
+}
diff --git a/vendor/petgraph/src/prelude.rs b/vendor/petgraph/src/prelude.rs
new file mode 100644
index 000000000..f50b338b2
--- /dev/null
+++ b/vendor/petgraph/src/prelude.rs
@@ -0,0 +1,21 @@
+//! Commonly used items.
+//!
+//! ```
+//! use petgraph::prelude::*;
+//! ```
+
+#[doc(no_inline)]
+pub use crate::graph::{DiGraph, EdgeIndex, Graph, NodeIndex, UnGraph};
+#[cfg(feature = "graphmap")]
+#[doc(no_inline)]
+pub use crate::graphmap::{DiGraphMap, GraphMap, UnGraphMap};
+#[doc(no_inline)]
+#[cfg(feature = "stable_graph")]
+pub use crate::stable_graph::{StableDiGraph, StableGraph, StableUnGraph};
+#[doc(no_inline)]
+pub use crate::visit::{Bfs, Dfs, DfsPostOrder};
+#[doc(no_inline)]
+pub use crate::{Directed, Direction, Incoming, Outgoing, Undirected};
+
+#[doc(no_inline)]
+pub use crate::visit::EdgeRef;
diff --git a/vendor/petgraph/src/quickcheck.rs b/vendor/petgraph/src/quickcheck.rs
new file mode 100644
index 000000000..0c7ce6b2e
--- /dev/null
+++ b/vendor/petgraph/src/quickcheck.rs
@@ -0,0 +1,216 @@
+extern crate quickcheck;
+use self::quickcheck::{Arbitrary, Gen};
+
+use crate::graph::{node_index, IndexType};
+#[cfg(feature = "stable_graph")]
+use crate::stable_graph::StableGraph;
+use crate::{EdgeType, Graph};
+
+#[cfg(feature = "graphmap")]
+use crate::graphmap::{GraphMap, NodeTrait};
+use crate::visit::NodeIndexable;
+
+/// Return a random float in the range [0, 1.)
+fn random_01<G: Gen>(g: &mut G) -> f64 {
+ // from rand
+ let bits = 53;
+ let scale = 1. / ((1u64 << bits) as f64);
+ let x = g.next_u64();
+ (x >> (64 - bits)) as f64 * scale
+}
+
+/// `Arbitrary` for `Graph` creates a graph by selecting a node count
+/// and a probability for each possible edge to exist.
+///
+/// The result will be simple graph or digraph, self loops
+/// possible, no parallel edges.
+///
+/// The exact properties of the produced graph is subject to change.
+///
+/// Requires crate feature `"quickcheck"`
+impl<N, E, Ty, Ix> Arbitrary for Graph<N, E, Ty, Ix>
+where
+ N: Arbitrary,
+ E: Arbitrary,
+ Ty: EdgeType + Send + 'static,
+ Ix: IndexType + Send,
+{
+ fn arbitrary<G: Gen>(g: &mut G) -> Self {
+ let nodes = usize::arbitrary(g);
+ if nodes == 0 {
+ return Graph::with_capacity(0, 0);
+ }
+ // use X² for edge probability (bias towards lower)
+ let edge_prob = random_01(g) * random_01(g);
+ let edges = ((nodes as f64).powi(2) * edge_prob) as usize;
+ let mut gr = Graph::with_capacity(nodes, edges);
+ for _ in 0..nodes {
+ gr.add_node(N::arbitrary(g));
+ }
+ for i in gr.node_indices() {
+ for j in gr.node_indices() {
+ if !gr.is_directed() && i > j {
+ continue;
+ }
+ let p: f64 = random_01(g);
+ if p <= edge_prob {
+ gr.add_edge(i, j, E::arbitrary(g));
+ }
+ }
+ }
+ gr
+ }
+
+ // shrink the graph by splitting it in two by a very
+ // simple algorithm, just even and odd node indices
+ fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+ let self_ = self.clone();
+ Box::new((0..2).filter_map(move |x| {
+ let gr = self_.filter_map(
+ |i, w| {
+ if i.index() % 2 == x {
+ Some(w.clone())
+ } else {
+ None
+ }
+ },
+ |_, w| Some(w.clone()),
+ );
+ // make sure we shrink
+ if gr.node_count() < self_.node_count() {
+ Some(gr)
+ } else {
+ None
+ }
+ }))
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+/// `Arbitrary` for `StableGraph` creates a graph by selecting a node count
+/// and a probability for each possible edge to exist.
+///
+/// The result will be simple graph or digraph, with possible
+/// self loops, no parallel edges.
+///
+/// The exact properties of the produced graph is subject to change.
+///
+/// Requires crate features `"quickcheck"` and `"stable_graph"`
+impl<N, E, Ty, Ix> Arbitrary for StableGraph<N, E, Ty, Ix>
+where
+ N: Arbitrary,
+ E: Arbitrary,
+ Ty: EdgeType + Send + 'static,
+ Ix: IndexType + Send,
+{
+ fn arbitrary<G: Gen>(g: &mut G) -> Self {
+ let nodes = usize::arbitrary(g);
+ if nodes == 0 {
+ return StableGraph::with_capacity(0, 0);
+ }
+ // use X² for edge probability (bias towards lower)
+ let edge_prob = random_01(g) * random_01(g);
+ let edges = ((nodes as f64).powi(2) * edge_prob) as usize;
+ let mut gr = StableGraph::with_capacity(nodes, edges);
+ for _ in 0..nodes {
+ gr.add_node(N::arbitrary(g));
+ }
+ for i in 0..gr.node_count() {
+ for j in 0..gr.node_count() {
+ let i = node_index(i);
+ let j = node_index(j);
+ if !gr.is_directed() && i > j {
+ continue;
+ }
+ let p: f64 = random_01(g);
+ if p <= edge_prob {
+ gr.add_edge(i, j, E::arbitrary(g));
+ }
+ }
+ }
+ if bool::arbitrary(g) {
+ // potentially remove nodes to make holes in nodes & edge sets
+ let n = u8::arbitrary(g) % (gr.node_count() as u8);
+ for _ in 0..n {
+ let ni = node_index(usize::arbitrary(g) % gr.node_bound());
+ if gr.node_weight(ni).is_some() {
+ gr.remove_node(ni);
+ }
+ }
+ }
+ gr
+ }
+
+ // shrink the graph by splitting it in two by a very
+ // simple algorithm, just even and odd node indices
+ fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+ let self_ = self.clone();
+ Box::new((0..2).filter_map(move |x| {
+ let gr = self_.filter_map(
+ |i, w| {
+ if i.index() % 2 == x {
+ Some(w.clone())
+ } else {
+ None
+ }
+ },
+ |_, w| Some(w.clone()),
+ );
+ // make sure we shrink
+ if gr.node_count() < self_.node_count() {
+ Some(gr)
+ } else {
+ None
+ }
+ }))
+ }
+}
+
+/// `Arbitrary` for `GraphMap` creates a graph by selecting a node count
+/// and a probability for each possible edge to exist.
+///
+/// The result will be simple graph or digraph, self loops
+/// possible, no parallel edges.
+///
+/// The exact properties of the produced graph is subject to change.
+///
+/// Requires crate features `"quickcheck"` and `"graphmap"`
+#[cfg(feature = "graphmap")]
+impl<N, E, Ty> Arbitrary for GraphMap<N, E, Ty>
+where
+ N: NodeTrait + Arbitrary,
+ E: Arbitrary,
+ Ty: EdgeType + Clone + Send + 'static,
+{
+ fn arbitrary<G: Gen>(g: &mut G) -> Self {
+ let nodes = usize::arbitrary(g);
+ if nodes == 0 {
+ return GraphMap::with_capacity(0, 0);
+ }
+ let mut nodes = (0..nodes).map(|_| N::arbitrary(g)).collect::<Vec<_>>();
+ nodes.sort();
+ nodes.dedup();
+
+ // use X² for edge probability (bias towards lower)
+ let edge_prob = random_01(g) * random_01(g);
+ let edges = ((nodes.len() as f64).powi(2) * edge_prob) as usize;
+ let mut gr = GraphMap::with_capacity(nodes.len(), edges);
+ for &node in &nodes {
+ gr.add_node(node);
+ }
+ for (index, &i) in nodes.iter().enumerate() {
+ let js = if Ty::is_directed() {
+ &nodes[..]
+ } else {
+ &nodes[index..]
+ };
+ for &j in js {
+ let p: f64 = random_01(g);
+ if p <= edge_prob {
+ gr.add_edge(i, j, E::arbitrary(g));
+ }
+ }
+ }
+ gr
+ }
+}
diff --git a/vendor/petgraph/src/scored.rs b/vendor/petgraph/src/scored.rs
new file mode 100644
index 000000000..b4da04b4b
--- /dev/null
+++ b/vendor/petgraph/src/scored.rs
@@ -0,0 +1,52 @@
+use std::cmp::Ordering;
+
+/// `MinScored<K, T>` holds a score `K` and a scored object `T` in
+/// a pair for use with a `BinaryHeap`.
+///
+/// `MinScored` compares in reverse order by the score, so that we can
+/// use `BinaryHeap` as a min-heap to extract the score-value pair with the
+/// least score.
+///
+/// **Note:** `MinScored` implements a total order (`Ord`), so that it is
+/// possible to use float types as scores.
+#[derive(Copy, Clone, Debug)]
+pub struct MinScored<K, T>(pub K, pub T);
+
+impl<K: PartialOrd, T> PartialEq for MinScored<K, T> {
+ #[inline]
+ fn eq(&self, other: &MinScored<K, T>) -> bool {
+ self.cmp(other) == Ordering::Equal
+ }
+}
+
+impl<K: PartialOrd, T> Eq for MinScored<K, T> {}
+
+impl<K: PartialOrd, T> PartialOrd for MinScored<K, T> {
+ #[inline]
+ fn partial_cmp(&self, other: &MinScored<K, T>) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl<K: PartialOrd, T> Ord for MinScored<K, T> {
+ #[inline]
+ fn cmp(&self, other: &MinScored<K, T>) -> Ordering {
+ let a = &self.0;
+ let b = &other.0;
+ if a == b {
+ Ordering::Equal
+ } else if a < b {
+ Ordering::Greater
+ } else if a > b {
+ Ordering::Less
+ } else if a.ne(a) && b.ne(b) {
+ // these are the NaN cases
+ Ordering::Equal
+ } else if a.ne(a) {
+ // Order NaN less, so that it is last in the MinScore order
+ Ordering::Less
+ } else {
+ Ordering::Greater
+ }
+ }
+}
diff --git a/vendor/petgraph/src/serde_utils.rs b/vendor/petgraph/src/serde_utils.rs
new file mode 100644
index 000000000..f127f33be
--- /dev/null
+++ b/vendor/petgraph/src/serde_utils.rs
@@ -0,0 +1,95 @@
+use serde::de::{Deserialize, Error, SeqAccess, Visitor};
+use serde::ser::{Serialize, SerializeSeq, Serializer};
+use std::fmt;
+use std::marker::PhantomData;
+
+/// Map to serializeable representation
+pub trait IntoSerializable {
+ type Output;
+ fn into_serializable(self) -> Self::Output;
+}
+
+/// Map from deserialized representation
+pub trait FromDeserialized: Sized {
+ type Input;
+ fn from_deserialized<E>(input: Self::Input) -> Result<Self, E>
+ where
+ E: Error;
+}
+
+/// Serde combinator. A sequence visitor that maps deserialized elements
+/// lazily; the visitor can also emit new errors if the elements have errors.
+pub struct MappedSequenceVisitor<T, R, F>
+where
+ F: Fn(T) -> Result<R, &'static str>,
+{
+ f: F,
+ marker: PhantomData<fn() -> T>,
+}
+
+impl<'de, F, T, R> MappedSequenceVisitor<T, R, F>
+where
+ T: Deserialize<'de>,
+ F: Fn(T) -> Result<R, &'static str>,
+{
+ pub fn new(f: F) -> Self {
+ MappedSequenceVisitor {
+ f: f,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'de, F, T, R> Visitor<'de> for MappedSequenceVisitor<T, R, F>
+where
+ T: Deserialize<'de>,
+ F: Fn(T) -> Result<R, &'static str>,
+{
+ type Value = Vec<R>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "a sequence")
+ }
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut v = Vec::new();
+ while let Some(elem) = seq.next_element()? {
+ match (self.f)(elem) {
+ Err(s) => Err(<A::Error>::custom(s))?,
+ Ok(x) => v.push(x),
+ }
+ }
+ Ok(v)
+ }
+}
+
+pub trait CollectSeqWithLength: Serializer {
+ fn collect_seq_with_length<I>(self, length: usize, iterable: I) -> Result<Self::Ok, Self::Error>
+ where
+ I: IntoIterator,
+ I::Item: Serialize,
+ {
+ let mut count = 0;
+ let mut seq = self.serialize_seq(Some(length))?;
+ for element in iterable {
+ seq.serialize_element(&element)?;
+ count += 1;
+ }
+ debug_assert_eq!(length, count, "collect_seq_with_length: length mismatch!");
+ seq.end()
+ }
+
+ fn collect_seq_exact<I>(self, iterable: I) -> Result<Self::Ok, Self::Error>
+ where
+ I: IntoIterator,
+ I::Item: Serialize,
+ I::IntoIter: ExactSizeIterator,
+ {
+ let iter = iterable.into_iter();
+ self.collect_seq_with_length(iter.len(), iter)
+ }
+}
+
+impl<S> CollectSeqWithLength for S where S: Serializer {}
diff --git a/vendor/petgraph/src/simple_paths.rs b/vendor/petgraph/src/simple_paths.rs
new file mode 100644
index 000000000..59f0b9385
--- /dev/null
+++ b/vendor/petgraph/src/simple_paths.rs
@@ -0,0 +1,163 @@
+use std::{
+ hash::Hash,
+ iter::{from_fn, FromIterator},
+};
+
+use indexmap::IndexSet;
+
+use crate::{
+ visit::{IntoNeighborsDirected, NodeCount},
+ Direction::Outgoing,
+};
+
+/// Returns iterator that produces all simple paths from `from` node to `to`, which contains at least `min_intermediate_nodes` nodes
+/// and at most `max_intermediate_nodes`, if given, limited by graph's order otherwise
+/// Simple path is path without repetitions
+/// Algorithm is adopted from https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.simple_paths.all_simple_paths.html
+pub fn all_simple_paths<TargetColl, G>(
+ graph: G,
+ from: G::NodeId,
+ to: G::NodeId,
+ min_intermediate_nodes: usize,
+ max_intermediate_nodes: Option<usize>,
+) -> impl Iterator<Item = TargetColl>
+where
+ G: NodeCount,
+ G: IntoNeighborsDirected,
+ G::NodeId: Eq + Hash,
+ TargetColl: FromIterator<G::NodeId>,
+{
+ // how many nodes are allowed in simple path up to target node
+ // it is min/max allowed path length minus one, because it is more appropriate when implementing lookahead
+ // than constantly add 1 to length of current path
+ let max_length = if let Some(l) = max_intermediate_nodes {
+ l + 1
+ } else {
+ graph.node_count() - 1
+ };
+
+ let min_length = min_intermediate_nodes + 1;
+
+ // list of visited nodes
+ let mut visited: IndexSet<G::NodeId> = IndexSet::from_iter(Some(from));
+ // list of childs of currently exploring path nodes,
+ // last elem is list of childs of last visited node
+ let mut stack = vec![graph.neighbors_directed(from, Outgoing)];
+
+ from_fn(move || {
+ while let Some(children) = stack.last_mut() {
+ if let Some(child) = children.next() {
+ if visited.len() < max_length {
+ if child == to {
+ if visited.len() >= min_length {
+ let path = visited
+ .iter()
+ .cloned()
+ .chain(Some(to))
+ .collect::<TargetColl>();
+ return Some(path);
+ }
+ } else if !visited.contains(&child) {
+ visited.insert(child);
+ stack.push(graph.neighbors_directed(child, Outgoing));
+ }
+ } else {
+ if (child == to || children.any(|v| v == to)) && visited.len() >= min_length {
+ let path = visited
+ .iter()
+ .cloned()
+ .chain(Some(to))
+ .collect::<TargetColl>();
+ return Some(path);
+ }
+ stack.pop();
+ visited.pop();
+ }
+ } else {
+ stack.pop();
+ visited.pop();
+ }
+ }
+ None
+ })
+}
+
+#[cfg(test)]
+mod test {
+ use std::{collections::HashSet, iter::FromIterator};
+
+ use itertools::assert_equal;
+
+ use crate::{dot::Dot, prelude::DiGraph};
+
+ use super::all_simple_paths;
+
+ #[test]
+ fn test_all_simple_paths() {
+ let graph = DiGraph::<i32, i32, _>::from_edges(&[
+ (0, 1),
+ (0, 2),
+ (0, 3),
+ (1, 2),
+ (1, 3),
+ (2, 3),
+ (2, 4),
+ (3, 2),
+ (3, 4),
+ (4, 2),
+ (4, 5),
+ (5, 2),
+ (5, 3),
+ ]);
+
+ let expexted_simple_paths_0_to_5 = vec![
+ vec![0usize, 1, 2, 3, 4, 5],
+ vec![0, 1, 2, 4, 5],
+ vec![0, 1, 3, 2, 4, 5],
+ vec![0, 1, 3, 4, 5],
+ vec![0, 2, 3, 4, 5],
+ vec![0, 2, 4, 5],
+ vec![0, 3, 2, 4, 5],
+ vec![0, 3, 4, 5],
+ ];
+
+ println!("{}", Dot::new(&graph));
+ let actual_simple_paths_0_to_5: HashSet<Vec<_>> =
+ all_simple_paths(&graph, 0u32.into(), 5u32.into(), 0, None)
+ .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
+ .collect();
+ assert_eq!(actual_simple_paths_0_to_5.len(), 8);
+ assert_eq!(
+ HashSet::from_iter(expexted_simple_paths_0_to_5),
+ actual_simple_paths_0_to_5
+ );
+ }
+
+ #[test]
+ fn test_one_simple_path() {
+ let graph = DiGraph::<i32, i32, _>::from_edges(&[(0, 1), (2, 1)]);
+
+ let expexted_simple_paths_0_to_1 = &[vec![0usize, 1]];
+ println!("{}", Dot::new(&graph));
+ let actual_simple_paths_0_to_1: Vec<Vec<_>> =
+ all_simple_paths(&graph, 0u32.into(), 1u32.into(), 0, None)
+ .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
+ .collect();
+
+ assert_eq!(actual_simple_paths_0_to_1.len(), 1);
+ assert_equal(expexted_simple_paths_0_to_1, &actual_simple_paths_0_to_1);
+ }
+
+ #[test]
+ fn test_no_simple_paths() {
+ let graph = DiGraph::<i32, i32, _>::from_edges(&[(0, 1), (2, 1)]);
+
+ println!("{}", Dot::new(&graph));
+ let actual_simple_paths_0_to_2: Vec<Vec<_>> =
+ all_simple_paths(&graph, 0u32.into(), 2u32.into(), 0, None)
+ .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
+ .collect();
+
+ assert_eq!(actual_simple_paths_0_to_2.len(), 0);
+ }
+}
diff --git a/vendor/petgraph/src/traits_graph.rs b/vendor/petgraph/src/traits_graph.rs
new file mode 100644
index 000000000..272e9e7f1
--- /dev/null
+++ b/vendor/petgraph/src/traits_graph.rs
@@ -0,0 +1,73 @@
+use fixedbitset::FixedBitSet;
+
+use super::EdgeType;
+
+use super::graph::{Graph, IndexType, NodeIndex};
+#[cfg(feature = "stable_graph")]
+use crate::stable_graph::StableGraph;
+use crate::visit::EdgeRef;
+#[cfg(feature = "stable_graph")]
+use crate::visit::{IntoEdgeReferences, NodeIndexable};
+
+use super::visit::GetAdjacencyMatrix;
+
+/// The adjacency matrix for **Graph** is a bitmap that's computed by
+/// `.adjacency_matrix()`.
+impl<N, E, Ty, Ix> GetAdjacencyMatrix for Graph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type AdjMatrix = FixedBitSet;
+
+ fn adjacency_matrix(&self) -> FixedBitSet {
+ let n = self.node_count();
+ let mut matrix = FixedBitSet::with_capacity(n * n);
+ for edge in self.edge_references() {
+ let i = edge.source().index() * n + edge.target().index();
+ matrix.put(i);
+ if !self.is_directed() {
+ let j = edge.source().index() + n * edge.target().index();
+ matrix.put(j);
+ }
+ }
+ matrix
+ }
+
+ fn is_adjacent(&self, matrix: &FixedBitSet, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
+ let n = self.node_count();
+ let index = n * a.index() + b.index();
+ matrix.contains(index)
+ }
+}
+
+#[cfg(feature = "stable_graph")]
+/// The adjacency matrix for **Graph** is a bitmap that's computed by
+/// `.adjacency_matrix()`.
+impl<N, E, Ty, Ix> GetAdjacencyMatrix for StableGraph<N, E, Ty, Ix>
+where
+ Ty: EdgeType,
+ Ix: IndexType,
+{
+ type AdjMatrix = FixedBitSet;
+
+ fn adjacency_matrix(&self) -> FixedBitSet {
+ let n = self.node_bound();
+ let mut matrix = FixedBitSet::with_capacity(n * n);
+ for edge in self.edge_references() {
+ let i = edge.source().index() * n + edge.target().index();
+ matrix.put(i);
+ if !self.is_directed() {
+ let j = edge.source().index() + n * edge.target().index();
+ matrix.put(j);
+ }
+ }
+ matrix
+ }
+
+ fn is_adjacent(&self, matrix: &FixedBitSet, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
+ let n = self.node_count();
+ let index = n * a.index() + b.index();
+ matrix.contains(index)
+ }
+}
diff --git a/vendor/petgraph/src/unionfind.rs b/vendor/petgraph/src/unionfind.rs
new file mode 100644
index 000000000..2f6b12c0b
--- /dev/null
+++ b/vendor/petgraph/src/unionfind.rs
@@ -0,0 +1,146 @@
+//! `UnionFind<K>` is a disjoint-set data structure.
+
+use super::graph::IndexType;
+use std::cmp::Ordering;
+
+/// `UnionFind<K>` is a disjoint-set data structure. It tracks set membership of *n* elements
+/// indexed from *0* to *n - 1*. The scalar type is `K` which must be an unsigned integer type.
+///
+/// <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>
+///
+/// Too awesome not to quote:
+///
+/// “The amortized time per operation is **O(α(n))** where **α(n)** is the
+/// inverse of **f(x) = A(x, x)** with **A** being the extremely fast-growing Ackermann function.”
+#[derive(Debug, Clone)]
+pub struct UnionFind<K> {
+ // For element at index *i*, store the index of its parent; the representative itself
+ // stores its own index. This forms equivalence classes which are the disjoint sets, each
+ // with a unique representative.
+ parent: Vec<K>,
+ // It is a balancing tree structure,
+ // so the ranks are logarithmic in the size of the container -- a byte is more than enough.
+ //
+ // Rank is separated out both to save space and to save cache in when searching in the parent
+ // vector.
+ rank: Vec<u8>,
+}
+
+#[inline]
+unsafe fn get_unchecked<K>(xs: &[K], index: usize) -> &K {
+ debug_assert!(index < xs.len());
+ xs.get_unchecked(index)
+}
+
+#[inline]
+unsafe fn get_unchecked_mut<K>(xs: &mut [K], index: usize) -> &mut K {
+ debug_assert!(index < xs.len());
+ xs.get_unchecked_mut(index)
+}
+
+impl<K> UnionFind<K>
+where
+ K: IndexType,
+{
+ /// Create a new `UnionFind` of `n` disjoint sets.
+ pub fn new(n: usize) -> Self {
+ let rank = vec![0; n];
+ let parent = (0..n).map(K::new).collect::<Vec<K>>();
+
+ UnionFind { parent, rank }
+ }
+
+ /// Return the representative for `x`.
+ ///
+ /// **Panics** if `x` is out of bounds.
+ pub fn find(&self, x: K) -> K {
+ assert!(x.index() < self.parent.len());
+ unsafe {
+ let mut x = x;
+ loop {
+ // Use unchecked indexing because we can trust the internal set ids.
+ let xparent = *get_unchecked(&self.parent, x.index());
+ if xparent == x {
+ break;
+ }
+ x = xparent;
+ }
+ x
+ }
+ }
+
+ /// Return the representative for `x`.
+ ///
+ /// Write back the found representative, flattening the internal
+ /// datastructure in the process and quicken future lookups.
+ ///
+ /// **Panics** if `x` is out of bounds.
+ pub fn find_mut(&mut self, x: K) -> K {
+ assert!(x.index() < self.parent.len());
+ unsafe { self.find_mut_recursive(x) }
+ }
+
+ unsafe fn find_mut_recursive(&mut self, mut x: K) -> K {
+ let mut parent = *get_unchecked(&self.parent, x.index());
+ while parent != x {
+ let grandparent = *get_unchecked(&self.parent, parent.index());
+ *get_unchecked_mut(&mut self.parent, x.index()) = grandparent;
+ x = parent;
+ parent = grandparent;
+ }
+ x
+ }
+
+ /// Returns `true` if the given elements belong to the same set, and returns
+ /// `false` otherwise.
+ pub fn equiv(&self, x: K, y: K) -> bool {
+ self.find(x) == self.find(y)
+ }
+
+ /// Unify the two sets containing `x` and `y`.
+ ///
+ /// Return `false` if the sets were already the same, `true` if they were unified.
+ ///
+ /// **Panics** if `x` or `y` is out of bounds.
+ pub fn union(&mut self, x: K, y: K) -> bool {
+ if x == y {
+ return false;
+ }
+ let xrep = self.find_mut(x);
+ let yrep = self.find_mut(y);
+
+ if xrep == yrep {
+ return false;
+ }
+
+ let xrepu = xrep.index();
+ let yrepu = yrep.index();
+ let xrank = self.rank[xrepu];
+ let yrank = self.rank[yrepu];
+
+ // The rank corresponds roughly to the depth of the treeset, so put the
+ // smaller set below the larger
+ match xrank.cmp(&yrank) {
+ Ordering::Less => self.parent[xrepu] = yrep,
+ Ordering::Greater => self.parent[yrepu] = xrep,
+ Ordering::Equal => {
+ self.parent[yrepu] = xrep;
+ self.rank[xrepu] += 1;
+ }
+ }
+ true
+ }
+
+ /// Return a vector mapping each element to its representative.
+ pub fn into_labeling(mut self) -> Vec<K> {
+ // write in the labeling of each element
+ unsafe {
+ for ix in 0..self.parent.len() {
+ let k = *get_unchecked(&self.parent, ix);
+ let xrep = self.find_mut_recursive(k);
+ *self.parent.get_unchecked_mut(ix) = xrep;
+ }
+ }
+ self.parent
+ }
+}
diff --git a/vendor/petgraph/src/util.rs b/vendor/petgraph/src/util.rs
new file mode 100644
index 000000000..f4d28d9d4
--- /dev/null
+++ b/vendor/petgraph/src/util.rs
@@ -0,0 +1,25 @@
+use std::iter;
+
+pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
+where
+ I: IntoIterator,
+{
+ iterable.into_iter().enumerate()
+}
+
+#[cfg(feature = "serde-1")]
+pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
+where
+ I: IntoIterator,
+ I::IntoIter: DoubleEndedIterator,
+{
+ iterable.into_iter().rev()
+}
+
+pub fn zip<I, J>(i: I, j: J) -> iter::Zip<I::IntoIter, J::IntoIter>
+where
+ I: IntoIterator,
+ J: IntoIterator,
+{
+ i.into_iter().zip(j)
+}
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)
+ }
+}