yuuang_dominators/
graphmap.rs

1//! `GraphMap<N, E, Ty>` is a graph datastructure where node values are mapping
2//! keys.
3
4use indexmap::map::Keys;
5use indexmap::map::{Iter as IndexMapIter, IterMut as IndexMapIterMut};
6use indexmap::IndexMap;
7use std::cmp::Ordering;
8use std::collections::HashSet;
9use std::fmt;
10use std::hash::{self, Hash};
11use std::iter::FromIterator;
12use std::iter::{Cloned, DoubleEndedIterator};
13use std::marker::PhantomData;
14use std::mem;
15use std::ops::{Deref, Index, IndexMut};
16use std::slice::Iter;
17
18use crate::{Directed, Direction, EdgeType, Incoming, Outgoing, Undirected};
19
20use crate::graph::node_index;
21use crate::graph::Graph;
22use crate::visit;
23use crate::IntoWeightedEdge;
24
25/// A `GraphMap` with undirected edges.
26///
27/// For example, an edge between *1* and *2* is equivalent to an edge between
28/// *2* and *1*.
29pub type UnGraphMap<N, E> = GraphMap<N, E, Undirected>;
30/// A `GraphMap` with directed edges.
31///
32/// For example, an edge from *1* to *2* is distinct from an edge from *2* to
33/// *1*.
34pub type DiGraphMap<N, E> = GraphMap<N, E, Directed>;
35
36/// `GraphMap<N, E, Ty>` is a graph datastructure using an associative array
37/// of its node weights `N`.
38///
39/// It uses an combined adjacency list and sparse adjacency matrix
40/// representation, using **O(|V| + |E|)** space, and allows testing for edge
41/// existence in constant time.
42///
43/// `GraphMap` is parameterized over:
44///
45/// - Associated data `N` for nodes and `E` for edges, called *weights*.
46/// - The node weight `N` must implement `Copy` and will be used as node
47/// identifier, duplicated into several places in the data structure.
48/// It must be suitable as a hash table key (implementing `Eq + Hash`).
49/// The node type must also implement `Ord` so that the implementation can
50/// order the pair (`a`, `b`) for an edge connecting any two nodes `a` and `b`.
51/// - `E` can be of arbitrary type.
52/// - Edge type `Ty` that determines whether the graph edges are directed or
53/// undirected.
54///
55/// You can use the type aliases `UnGraphMap` and `DiGraphMap` for convenience.
56///
57/// `GraphMap` does not allow parallel edges, but self loops are allowed.
58///
59/// Depends on crate feature `graphmap` (default).
60#[derive(Clone)]
61pub struct GraphMap<N, E, Ty> {
62    nodes: IndexMap<N, Vec<(N, CompactDirection)>>,
63    edges: IndexMap<(N, N), E>,
64    ty: PhantomData<Ty>,
65}
66
67impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug, Ty: EdgeType> fmt::Debug for GraphMap<N, E, Ty> {
68    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69        self.nodes.fmt(f)
70    }
71}
72
73/// A trait group for `GraphMap`'s node identifier.
74pub trait NodeTrait: Copy + Ord + Hash {}
75impl<N> NodeTrait for N where N: Copy + Ord + Hash {}
76
77// non-repr(usize) version of Direction
78#[derive(Copy, Clone, Debug, PartialEq)]
79enum CompactDirection {
80    Outgoing,
81    Incoming,
82}
83
84impl CompactDirection {
85    /// Return the opposite `CompactDirection`.
86    #[inline]
87    pub fn opposite(self) -> CompactDirection {
88        match self {
89            CompactDirection::Outgoing => CompactDirection::Incoming,
90            CompactDirection::Incoming => CompactDirection::Outgoing,
91        }
92    }
93}
94
95impl From<Direction> for CompactDirection {
96    fn from(d: Direction) -> Self {
97        match d {
98            Outgoing => CompactDirection::Outgoing,
99            Incoming => CompactDirection::Incoming,
100        }
101    }
102}
103
104impl From<CompactDirection> for Direction {
105    fn from(d: CompactDirection) -> Self {
106        match d {
107            CompactDirection::Outgoing => Outgoing,
108            CompactDirection::Incoming => Incoming,
109        }
110    }
111}
112
113impl PartialEq<Direction> for CompactDirection {
114    fn eq(&self, rhs: &Direction) -> bool {
115        (*self as usize) == (*rhs as usize)
116    }
117}
118
119#[cfg(feature = "serde-1")]
120impl<N, E, Ty> serde::Serialize for GraphMap<N, E, Ty>
121where
122    Ty: EdgeType,
123    N: NodeTrait + serde::Serialize,
124    E: serde::Serialize,
125    GraphMap<N, E, Ty>: Clone,
126{
127    /// Serializes the given `GraphMap` into the same format as the standard
128    /// `Graph`. Needs feature `serde-1`.
129    ///
130    /// Note: the graph has to be `Clone` for this to work.
131    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
132    where
133        S: serde::Serializer,
134    {
135        let cloned_graph: GraphMap<N, E, Ty> = GraphMap::clone(self);
136        let equivalent_graph: Graph<N, E, Ty, u32> = cloned_graph.into_graph();
137        equivalent_graph.serialize(serializer)
138    }
139}
140
141#[cfg(feature = "serde-1")]
142impl<'de, N, E, Ty> serde::Deserialize<'de> for GraphMap<N, E, Ty>
143where
144    Ty: EdgeType,
145    N: NodeTrait + serde::Deserialize<'de>,
146    E: Clone + serde::Deserialize<'de>,
147{
148    /// Deserializes into a new `GraphMap` from the same format as the standard
149    /// `Graph`. Needs feature `serde-1`.
150    ///
151    /// **Warning**: When deseralizing a graph that was not originally a `GraphMap`,
152    /// the restrictions from [`from_graph`](#method.from_graph) apply.
153    ///
154    /// Note: The edge weights have to be `Clone` for this to work.
155    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
156    where
157        D: serde::Deserializer<'de>,
158    {
159        let equivalent_graph: Graph<N, E, Ty, u32> = Graph::deserialize(deserializer)?;
160        Ok(GraphMap::from_graph(equivalent_graph))
161    }
162}
163
164impl<N, E, Ty> GraphMap<N, E, Ty>
165where
166    N: NodeTrait,
167    Ty: EdgeType,
168{
169    /// Create a new `GraphMap`
170    pub fn new() -> Self {
171        Self::default()
172    }
173
174    /// Create a new `GraphMap` with estimated capacity.
175    pub fn with_capacity(nodes: usize, edges: usize) -> Self {
176        GraphMap {
177            nodes: IndexMap::with_capacity(nodes),
178            edges: IndexMap::with_capacity(edges),
179            ty: PhantomData,
180        }
181    }
182
183    /// Return the current node and edge capacity of the graph.
184    pub fn capacity(&self) -> (usize, usize) {
185        (self.nodes.capacity(), self.edges.capacity())
186    }
187
188    /// Use their natural order to map the node pair (a, b) to a canonical edge id.
189    #[inline]
190    fn edge_key(a: N, b: N) -> (N, N) {
191        if Ty::is_directed() || a <= b {
192            (a, b)
193        } else {
194            (b, a)
195        }
196    }
197
198    /// Whether the graph has directed edges.
199    pub fn is_directed(&self) -> bool {
200        Ty::is_directed()
201    }
202
203    /// Create a new `GraphMap` from an iterable of edges.
204    ///
205    /// Node values are taken directly from the list.
206    /// Edge weights `E` may either be specified in the list,
207    /// or they are filled with default values.
208    ///
209    /// Nodes are inserted automatically to match the edges.
210    ///
211    /// ```
212    /// use petgraph::graphmap::UnGraphMap;
213    ///
214    /// // Create a new undirected GraphMap.
215    /// // Use a type hint to have `()` be the edge weight type.
216    /// let gr = UnGraphMap::<_, ()>::from_edges(&[
217    ///     (0, 1), (0, 2), (0, 3),
218    ///     (1, 2), (1, 3),
219    ///     (2, 3),
220    /// ]);
221    /// ```
222    pub fn from_edges<I>(iterable: I) -> Self
223    where
224        I: IntoIterator,
225        I::Item: IntoWeightedEdge<E, NodeId = N>,
226    {
227        Self::from_iter(iterable)
228    }
229
230    /// Return the number of nodes in the graph.
231    pub fn node_count(&self) -> usize {
232        self.nodes.len()
233    }
234
235    /// Return the number of edges in the graph.
236    pub fn edge_count(&self) -> usize {
237        self.edges.len()
238    }
239
240    /// Remove all nodes and edges
241    pub fn clear(&mut self) {
242        self.nodes.clear();
243        self.edges.clear();
244    }
245
246    /// Add node `n` to the graph.
247    pub fn add_node(&mut self, n: N) -> N {
248        self.nodes.entry(n).or_insert(Vec::new());
249        n
250    }
251
252    /// Return `true` if node `n` was removed.
253    ///
254    /// Computes in **O(V)** time, due to the removal of edges with other nodes.
255    pub fn remove_node(&mut self, n: N) -> bool {
256        let links = match self.nodes.swap_remove(&n) {
257            None => return false,
258            Some(sus) => sus,
259        };
260        for (succ, dir) in links {
261            let edge = if dir == CompactDirection::Outgoing {
262                Self::edge_key(n, succ)
263            } else {
264                Self::edge_key(succ, n)
265            };
266            // remove all successor links
267            self.remove_single_edge(&succ, &n, dir.opposite());
268            // Remove all edge values
269            self.edges.swap_remove(&edge);
270        }
271        true
272    }
273
274    /// Return `true` if the node is contained in the graph.
275    pub fn contains_node(&self, n: N) -> bool {
276        self.nodes.contains_key(&n)
277    }
278
279    /// Add an edge connecting `a` and `b` to the graph, with associated
280    /// data `weight`. For a directed graph, the edge is directed from `a`
281    /// to `b`.
282    ///
283    /// Inserts nodes `a` and/or `b` if they aren't already part of the graph.
284    ///
285    /// Return `None` if the edge did not previously exist, otherwise,
286    /// the associated data is updated and the old value is returned
287    /// as `Some(old_weight)`.
288    ///
289    /// ```
290    /// // Create a GraphMap with directed edges, and add one edge to it
291    /// use petgraph::graphmap::DiGraphMap;
292    ///
293    /// let mut g = DiGraphMap::new();
294    /// g.add_edge("x", "y", -1);
295    /// assert_eq!(g.node_count(), 2);
296    /// assert_eq!(g.edge_count(), 1);
297    /// assert!(g.contains_edge("x", "y"));
298    /// assert!(!g.contains_edge("y", "x"));
299    /// ```
300    pub fn add_edge(&mut self, a: N, b: N, weight: E) -> Option<E> {
301        if let old @ Some(_) = self.edges.insert(Self::edge_key(a, b), weight) {
302            old
303        } else {
304            // insert in the adjacency list if it's a new edge
305            self.nodes
306                .entry(a)
307                .or_insert_with(|| Vec::with_capacity(1))
308                .push((b, CompactDirection::Outgoing));
309            if a != b {
310                // self loops don't have the Incoming entry
311                self.nodes
312                    .entry(b)
313                    .or_insert_with(|| Vec::with_capacity(1))
314                    .push((a, CompactDirection::Incoming));
315            }
316            None
317        }
318    }
319
320    /// Remove edge relation from a to b
321    ///
322    /// Return `true` if it did exist.
323    fn remove_single_edge(&mut self, a: &N, b: &N, dir: CompactDirection) -> bool {
324        match self.nodes.get_mut(a) {
325            None => false,
326            Some(sus) => {
327                if Ty::is_directed() {
328                    match sus.iter().position(|elt| elt == &(*b, dir)) {
329                        Some(index) => {
330                            sus.swap_remove(index);
331                            true
332                        }
333                        None => false,
334                    }
335                } else {
336                    match sus.iter().position(|elt| &elt.0 == b) {
337                        Some(index) => {
338                            sus.swap_remove(index);
339                            true
340                        }
341                        None => false,
342                    }
343                }
344            }
345        }
346    }
347
348    /// Remove edge from `a` to `b` from the graph and return the edge weight.
349    ///
350    /// Return `None` if the edge didn't exist.
351    ///
352    /// ```
353    /// // Create a GraphMap with undirected edges, and add and remove an edge.
354    /// use petgraph::graphmap::UnGraphMap;
355    ///
356    /// let mut g = UnGraphMap::new();
357    /// g.add_edge("x", "y", -1);
358    ///
359    /// let edge_data = g.remove_edge("y", "x");
360    /// assert_eq!(edge_data, Some(-1));
361    /// assert_eq!(g.edge_count(), 0);
362    /// ```
363    pub fn remove_edge(&mut self, a: N, b: N) -> Option<E> {
364        let exist1 = self.remove_single_edge(&a, &b, CompactDirection::Outgoing);
365        let exist2 = if a != b {
366            self.remove_single_edge(&b, &a, CompactDirection::Incoming)
367        } else {
368            exist1
369        };
370        let weight = self.edges.remove(&Self::edge_key(a, b));
371        debug_assert!(exist1 == exist2 && exist1 == weight.is_some());
372        weight
373    }
374
375    /// Return `true` if the edge connecting `a` with `b` is contained in the graph.
376    pub fn contains_edge(&self, a: N, b: N) -> bool {
377        self.edges.contains_key(&Self::edge_key(a, b))
378    }
379
380    /// Return an iterator over the nodes of the graph.
381    ///
382    /// Iterator element type is `N`.
383    pub fn nodes(&self) -> Nodes<N> {
384        Nodes {
385            iter: self.nodes.keys().cloned(),
386        }
387    }
388
389    /// Return an iterator of all nodes with an edge starting from `a`.
390    ///
391    /// - `Directed`: Outgoing edges from `a`.
392    /// - `Undirected`: All edges from or to `a`.
393    ///
394    /// Produces an empty iterator if the node doesn't exist.<br>
395    /// Iterator element type is `N`.
396    pub fn neighbors(&self, a: N) -> Neighbors<N, Ty> {
397        Neighbors {
398            iter: match self.nodes.get(&a) {
399                Some(neigh) => neigh.iter(),
400                None => [].iter(),
401            },
402            ty: self.ty,
403        }
404    }
405
406    /// Return an iterator of all neighbors that have an edge between them and
407    /// `a`, in the specified direction.
408    /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*.
409    ///
410    /// - `Directed`, `Outgoing`: All edges from `a`.
411    /// - `Directed`, `Incoming`: All edges to `a`.
412    /// - `Undirected`: All edges from or to `a`.
413    ///
414    /// Produces an empty iterator if the node doesn't exist.<br>
415    /// Iterator element type is `N`.
416    pub fn neighbors_directed(&self, a: N, dir: Direction) -> NeighborsDirected<N, Ty> {
417        NeighborsDirected {
418            iter: match self.nodes.get(&a) {
419                Some(neigh) => neigh.iter(),
420                None => [].iter(),
421            },
422            start_node: a,
423            dir,
424            ty: self.ty,
425        }
426    }
427
428    /// Return an iterator of target nodes with an edge starting from `a`,
429    /// paired with their respective edge weights.
430    ///
431    /// - `Directed`: Outgoing edges from `a`.
432    /// - `Undirected`: All edges from or to `a`.
433    ///
434    /// Produces an empty iterator if the node doesn't exist.<br>
435    /// Iterator element type is `(N, &E)`.
436    pub fn edges(&self, from: N) -> Edges<N, E, Ty> {
437        Edges {
438            from,
439            iter: self.neighbors(from),
440            edges: &self.edges,
441        }
442    }
443
444    /// Return an iterator of target nodes with an edge starting from `a`,
445    /// paired with their respective edge weights.
446    ///
447    /// - `Directed`, `Outgoing`: All edges from `a`.
448    /// - `Directed`, `Incoming`: All edges to `a`.
449    /// - `Undirected`, `Outgoing`: All edges connected to `a`, with `a` being the source of each
450    ///   edge.
451    /// - `Undirected`, `Incoming`: All edges connected to `a`, with `a` being the target of each
452    ///   edge.
453    ///
454    /// Produces an empty iterator if the node doesn't exist.<br>
455    /// Iterator element type is `(N, &E)`.
456    pub fn edges_directed(&self, from: N, dir: Direction) -> EdgesDirected<N, E, Ty> {
457        EdgesDirected {
458            from,
459            iter: self.neighbors_directed(from, dir),
460            dir,
461            edges: &self.edges,
462        }
463    }
464
465    /// Return a reference to the edge weight connecting `a` with `b`, or
466    /// `None` if the edge does not exist in the graph.
467    pub fn edge_weight(&self, a: N, b: N) -> Option<&E> {
468        self.edges.get(&Self::edge_key(a, b))
469    }
470
471    /// Return a mutable reference to the edge weight connecting `a` with `b`, or
472    /// `None` if the edge does not exist in the graph.
473    pub fn edge_weight_mut(&mut self, a: N, b: N) -> Option<&mut E> {
474        self.edges.get_mut(&Self::edge_key(a, b))
475    }
476
477    /// Return an iterator over all edges of the graph with their weight in arbitrary order.
478    ///
479    /// Iterator element type is `(N, N, &E)`
480    pub fn all_edges(&self) -> AllEdges<N, E, Ty> {
481        AllEdges {
482            inner: self.edges.iter(),
483            ty: self.ty,
484        }
485    }
486
487    /// Return an iterator over all edges of the graph in arbitrary order, with a mutable reference
488    /// to their weight.
489    ///
490    /// Iterator element type is `(N, N, &mut E)`
491    pub fn all_edges_mut(&mut self) -> AllEdgesMut<N, E, Ty> {
492        AllEdgesMut {
493            inner: self.edges.iter_mut(),
494            ty: self.ty,
495        }
496    }
497
498    /// Return a `Graph` that corresponds to this `GraphMap`.
499    ///
500    /// 1. Note that node and edge indices in the `Graph` have nothing in common
501    ///    with the `GraphMap`s node weights `N`. The node weights `N` are used as
502    ///    node weights in the resulting `Graph`, too.
503    /// 2. Note that the index type is user-chosen.
504    ///
505    /// Computes in **O(|V| + |E|)** time (average).
506    ///
507    /// **Panics** if the number of nodes or edges does not fit with
508    /// the resulting graph's index type.
509    pub fn into_graph<Ix>(self) -> Graph<N, E, Ty, Ix>
510    where
511        Ix: crate::graph::IndexType,
512    {
513        // assuming two successive iterations of the same hashmap produce the same order
514        let mut gr = Graph::with_capacity(self.node_count(), self.edge_count());
515        for (&node, _) in &self.nodes {
516            gr.add_node(node);
517        }
518        for ((a, b), edge_weight) in self.edges {
519            let (ai, _, _) = self.nodes.get_full(&a).unwrap();
520            let (bi, _, _) = self.nodes.get_full(&b).unwrap();
521            gr.add_edge(node_index(ai), node_index(bi), edge_weight);
522        }
523        gr
524    }
525
526    /// Creates a `GraphMap` that corresponds to the given `Graph`.
527    ///
528    /// **Warning**: Nodes with the same weight are merged and only the last parallel edge
529    /// is kept. Node and edge indices of the `Graph` are lost. Only use this function
530    /// if the node weights are distinct and there are no parallel edges.
531    ///
532    /// Computes in **O(|V| + |E|)** time (average).
533    pub fn from_graph<Ix>(graph: Graph<N, E, Ty, Ix>) -> Self
534    where
535        Ix: crate::graph::IndexType,
536        E: Clone,
537    {
538        let mut new_graph: GraphMap<N, E, Ty> =
539            GraphMap::with_capacity(graph.node_count(), graph.edge_count());
540
541        for node in graph.raw_nodes() {
542            new_graph.add_node(node.weight);
543        }
544
545        for edge in graph.edge_indices() {
546            let (a, b) = graph.edge_endpoints(edge).unwrap();
547            new_graph.add_edge(
548                *graph.node_weight(a).unwrap(),
549                *graph.node_weight(b).unwrap(),
550                graph.edge_weight(edge).unwrap().clone(),
551            );
552        }
553
554        new_graph
555    }
556}
557
558/// Create a new `GraphMap` from an iterable of edges.
559impl<N, E, Ty, Item> FromIterator<Item> for GraphMap<N, E, Ty>
560where
561    Item: IntoWeightedEdge<E, NodeId = N>,
562    N: NodeTrait,
563    Ty: EdgeType,
564{
565    fn from_iter<I>(iterable: I) -> Self
566    where
567        I: IntoIterator<Item = Item>,
568    {
569        let iter = iterable.into_iter();
570        let (low, _) = iter.size_hint();
571        let mut g = Self::with_capacity(0, low);
572        g.extend(iter);
573        g
574    }
575}
576
577/// Extend the graph from an iterable of edges.
578///
579/// Nodes are inserted automatically to match the edges.
580impl<N, E, Ty, Item> Extend<Item> for GraphMap<N, E, Ty>
581where
582    Item: IntoWeightedEdge<E, NodeId = N>,
583    N: NodeTrait,
584    Ty: EdgeType,
585{
586    fn extend<I>(&mut self, iterable: I)
587    where
588        I: IntoIterator<Item = Item>,
589    {
590        let iter = iterable.into_iter();
591        let (low, _) = iter.size_hint();
592        self.edges.reserve(low);
593
594        for elt in iter {
595            let (source, target, weight) = elt.into_weighted_edge();
596            self.add_edge(source, target, weight);
597        }
598    }
599}
600
601iterator_wrap! {
602    impl (Iterator DoubleEndedIterator ExactSizeIterator) for
603    #[derive(Debug, Clone)]
604    struct Nodes <'a, N> where { N: 'a + NodeTrait }
605    item: N,
606    iter: Cloned<Keys<'a, N, Vec<(N, CompactDirection)>>>,
607}
608
609#[derive(Debug, Clone)]
610pub struct Neighbors<'a, N, Ty = Undirected>
611where
612    N: 'a,
613    Ty: EdgeType,
614{
615    iter: Iter<'a, (N, CompactDirection)>,
616    ty: PhantomData<Ty>,
617}
618
619impl<'a, N, Ty> Iterator for Neighbors<'a, N, Ty>
620where
621    N: NodeTrait,
622    Ty: EdgeType,
623{
624    type Item = N;
625    fn next(&mut self) -> Option<N> {
626        if Ty::is_directed() {
627            (&mut self.iter)
628                .filter_map(|&(n, dir)| if dir == Outgoing { Some(n) } else { None })
629                .next()
630        } else {
631            self.iter.next().map(|&(n, _)| n)
632        }
633    }
634    fn size_hint(&self) -> (usize, Option<usize>) {
635        let (lower, upper) = self.iter.size_hint();
636        if Ty::is_directed() {
637            (0, upper)
638        } else {
639            (lower, upper)
640        }
641    }
642}
643
644#[derive(Debug, Clone)]
645pub struct NeighborsDirected<'a, N, Ty>
646where
647    N: 'a,
648    Ty: EdgeType,
649{
650    iter: Iter<'a, (N, CompactDirection)>,
651    start_node: N,
652    dir: Direction,
653    ty: PhantomData<Ty>,
654}
655
656impl<'a, N, Ty> Iterator for NeighborsDirected<'a, N, Ty>
657where
658    N: NodeTrait,
659    Ty: EdgeType,
660{
661    type Item = N;
662    fn next(&mut self) -> Option<N> {
663        if Ty::is_directed() {
664            let self_dir = self.dir;
665            let start_node = self.start_node;
666            (&mut self.iter)
667                .filter_map(move |&(n, dir)| {
668                    if dir == self_dir || n == start_node {
669                        Some(n)
670                    } else {
671                        None
672                    }
673                })
674                .next()
675        } else {
676            self.iter.next().map(|&(n, _)| n)
677        }
678    }
679    fn size_hint(&self) -> (usize, Option<usize>) {
680        let (lower, upper) = self.iter.size_hint();
681        if Ty::is_directed() {
682            (0, upper)
683        } else {
684            (lower, upper)
685        }
686    }
687}
688
689#[derive(Debug, Clone)]
690pub struct Edges<'a, N, E: 'a, Ty>
691where
692    N: 'a + NodeTrait,
693    Ty: EdgeType,
694{
695    from: N,
696    edges: &'a IndexMap<(N, N), E>,
697    iter: Neighbors<'a, N, Ty>,
698}
699
700impl<'a, N, E, Ty> Iterator for Edges<'a, N, E, Ty>
701where
702    N: 'a + NodeTrait,
703    E: 'a,
704    Ty: EdgeType,
705{
706    type Item = (N, N, &'a E);
707    fn next(&mut self) -> Option<Self::Item> {
708        self.iter.next().map(|b| {
709            let a = self.from;
710            match self.edges.get(&GraphMap::<N, E, Ty>::edge_key(a, b)) {
711                None => unreachable!(),
712                Some(edge) => (a, b, edge),
713            }
714        })
715    }
716    fn size_hint(&self) -> (usize, Option<usize>) {
717        self.iter.size_hint()
718    }
719}
720
721#[derive(Debug, Clone)]
722pub struct EdgesDirected<'a, N, E: 'a, Ty>
723where
724    N: 'a + NodeTrait,
725    Ty: EdgeType,
726{
727    from: N,
728    dir: Direction,
729    edges: &'a IndexMap<(N, N), E>,
730    iter: NeighborsDirected<'a, N, Ty>,
731}
732
733impl<'a, N, E, Ty> Iterator for EdgesDirected<'a, N, E, Ty>
734where
735    N: 'a + NodeTrait,
736    E: 'a,
737    Ty: EdgeType,
738{
739    type Item = (N, N, &'a E);
740    fn next(&mut self) -> Option<Self::Item> {
741        self.iter.next().map(|mut b| {
742            let mut a = self.from;
743            if self.dir == Direction::Incoming {
744                mem::swap(&mut a, &mut b);
745            }
746            match self.edges.get(&GraphMap::<N, E, Ty>::edge_key(a, b)) {
747                None => unreachable!(),
748                Some(edge) => (a, b, edge),
749            }
750        })
751    }
752    fn size_hint(&self) -> (usize, Option<usize>) {
753        self.iter.size_hint()
754    }
755}
756
757#[derive(Debug, Clone)]
758pub struct AllEdges<'a, N, E: 'a, Ty>
759where
760    N: 'a + NodeTrait,
761{
762    inner: IndexMapIter<'a, (N, N), E>,
763    ty: PhantomData<Ty>,
764}
765
766impl<'a, N, E, Ty> Iterator for AllEdges<'a, N, E, Ty>
767where
768    N: 'a + NodeTrait,
769    E: 'a,
770    Ty: EdgeType,
771{
772    type Item = (N, N, &'a E);
773    fn next(&mut self) -> Option<Self::Item> {
774        self.inner.next().map(|(&(a, b), v)| (a, b, v))
775    }
776
777    fn size_hint(&self) -> (usize, Option<usize>) {
778        self.inner.size_hint()
779    }
780
781    fn count(self) -> usize {
782        self.inner.count()
783    }
784
785    fn nth(&mut self, n: usize) -> Option<Self::Item> {
786        self.inner
787            .nth(n)
788            .map(|(&(n1, n2), weight)| (n1, n2, weight))
789    }
790
791    fn last(self) -> Option<Self::Item> {
792        self.inner
793            .last()
794            .map(|(&(n1, n2), weight)| (n1, n2, weight))
795    }
796}
797
798impl<'a, N, E, Ty> DoubleEndedIterator for AllEdges<'a, N, E, Ty>
799where
800    N: 'a + NodeTrait,
801    E: 'a,
802    Ty: EdgeType,
803{
804    fn next_back(&mut self) -> Option<Self::Item> {
805        self.inner
806            .next_back()
807            .map(|(&(n1, n2), weight)| (n1, n2, weight))
808    }
809}
810
811pub struct AllEdgesMut<'a, N, E: 'a, Ty>
812where
813    N: 'a + NodeTrait,
814{
815    inner: IndexMapIterMut<'a, (N, N), E>, // TODO: change to something that implements Debug + Clone?
816    ty: PhantomData<Ty>,
817}
818
819impl<'a, N, E, Ty> Iterator for AllEdgesMut<'a, N, E, Ty>
820where
821    N: 'a + NodeTrait,
822    E: 'a,
823    Ty: EdgeType,
824{
825    type Item = (N, N, &'a mut E);
826    fn next(&mut self) -> Option<Self::Item> {
827        self.inner
828            .next()
829            .map(|(&(n1, n2), weight)| (n1, n2, weight))
830    }
831
832    fn size_hint(&self) -> (usize, Option<usize>) {
833        self.inner.size_hint()
834    }
835
836    fn count(self) -> usize {
837        self.inner.count()
838    }
839
840    fn nth(&mut self, n: usize) -> Option<Self::Item> {
841        self.inner
842            .nth(n)
843            .map(|(&(n1, n2), weight)| (n1, n2, weight))
844    }
845
846    fn last(self) -> Option<Self::Item> {
847        self.inner
848            .last()
849            .map(|(&(n1, n2), weight)| (n1, n2, weight))
850    }
851}
852
853impl<'a, N, E, Ty> DoubleEndedIterator for AllEdgesMut<'a, N, E, Ty>
854where
855    N: 'a + NodeTrait,
856    E: 'a,
857    Ty: EdgeType,
858{
859    fn next_back(&mut self) -> Option<Self::Item> {
860        self.inner
861            .next_back()
862            .map(|(&(n1, n2), weight)| (n1, n2, weight))
863    }
864}
865
866/// Index `GraphMap` by node pairs to access edge weights.
867impl<N, E, Ty> Index<(N, N)> for GraphMap<N, E, Ty>
868where
869    N: NodeTrait,
870    Ty: EdgeType,
871{
872    type Output = E;
873    fn index(&self, index: (N, N)) -> &E {
874        let index = Self::edge_key(index.0, index.1);
875        self.edge_weight(index.0, index.1)
876            .expect("GraphMap::index: no such edge")
877    }
878}
879
880/// Index `GraphMap` by node pairs to access edge weights.
881impl<N, E, Ty> IndexMut<(N, N)> for GraphMap<N, E, Ty>
882where
883    N: NodeTrait,
884    Ty: EdgeType,
885{
886    fn index_mut(&mut self, index: (N, N)) -> &mut E {
887        let index = Self::edge_key(index.0, index.1);
888        self.edge_weight_mut(index.0, index.1)
889            .expect("GraphMap::index: no such edge")
890    }
891}
892
893/// Create a new empty `GraphMap`.
894impl<N, E, Ty> Default for GraphMap<N, E, Ty>
895where
896    N: NodeTrait,
897    Ty: EdgeType,
898{
899    fn default() -> Self {
900        GraphMap::with_capacity(0, 0)
901    }
902}
903
904/// A reference that is hashed and compared by its pointer value.
905///
906/// `Ptr` is used for certain configurations of `GraphMap`,
907/// in particular in the combination where the node type for
908/// `GraphMap` is something of type for example `Ptr(&Cell<T>)`,
909/// with the `Cell<T>` being `TypedArena` allocated.
910pub struct Ptr<'b, T: 'b>(pub &'b T);
911
912impl<'b, T> Copy for Ptr<'b, T> {}
913impl<'b, T> Clone for Ptr<'b, T> {
914    fn clone(&self) -> Self {
915        *self
916    }
917}
918
919fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
920    a == b
921}
922
923impl<'b, T> PartialEq for Ptr<'b, T> {
924    /// Ptr compares by pointer equality, i.e if they point to the same value
925    fn eq(&self, other: &Ptr<'b, T>) -> bool {
926        ptr_eq(self.0, other.0)
927    }
928}
929
930impl<'b, T> PartialOrd for Ptr<'b, T> {
931    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
932        Some(self.cmp(other))
933    }
934}
935
936impl<'b, T> Ord for Ptr<'b, T> {
937    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
938    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
939        let a: *const T = self.0;
940        let b: *const T = other.0;
941        a.cmp(&b)
942    }
943}
944
945impl<'b, T> Deref for Ptr<'b, T> {
946    type Target = T;
947    fn deref(&self) -> &T {
948        self.0
949    }
950}
951
952impl<'b, T> Eq for Ptr<'b, T> {}
953
954impl<'b, T> Hash for Ptr<'b, T> {
955    fn hash<H: hash::Hasher>(&self, st: &mut H) {
956        let ptr = (self.0) as *const T;
957        ptr.hash(st)
958    }
959}
960
961impl<'b, T: fmt::Debug> fmt::Debug for Ptr<'b, T> {
962    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
963        self.0.fmt(f)
964    }
965}
966
967#[derive(Debug, Clone)]
968pub struct NodeIdentifiers<'a, N, E: 'a, Ty>
969where
970    N: 'a + NodeTrait,
971{
972    iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
973    ty: PhantomData<Ty>,
974    edge_ty: PhantomData<E>,
975}
976
977impl<'a, N, E, Ty> Iterator for NodeIdentifiers<'a, N, E, Ty>
978where
979    N: 'a + NodeTrait,
980    E: 'a,
981    Ty: EdgeType,
982{
983    type Item = N;
984    fn next(&mut self) -> Option<Self::Item> {
985        self.iter.next().map(|(&n, _)| n)
986    }
987    fn size_hint(&self) -> (usize, Option<usize>) {
988        self.iter.size_hint()
989    }
990}
991
992#[derive(Debug, Clone)]
993pub struct NodeReferences<'a, N, E: 'a, Ty>
994where
995    N: 'a + NodeTrait,
996{
997    iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
998    ty: PhantomData<Ty>,
999    edge_ty: PhantomData<E>,
1000}
1001
1002impl<'a, N, E, Ty> Iterator for NodeReferences<'a, N, E, Ty>
1003where
1004    N: 'a + NodeTrait,
1005    E: 'a,
1006    Ty: EdgeType,
1007{
1008    type Item = (N, &'a N);
1009    fn next(&mut self) -> Option<Self::Item> {
1010        self.iter.next().map(|(n, _)| (*n, n))
1011    }
1012    fn size_hint(&self) -> (usize, Option<usize>) {
1013        self.iter.size_hint()
1014    }
1015}
1016
1017impl<N, E, Ty> visit::GraphBase for GraphMap<N, E, Ty>
1018where
1019    N: Copy + PartialEq,
1020{
1021    type NodeId = N;
1022    type EdgeId = (N, N);
1023}
1024
1025impl<N, E, Ty> visit::Data for GraphMap<N, E, Ty>
1026where
1027    N: Copy + PartialEq,
1028    Ty: EdgeType,
1029{
1030    type NodeWeight = N;
1031    type EdgeWeight = E;
1032}
1033
1034impl<N, E, Ty> visit::Visitable for GraphMap<N, E, Ty>
1035where
1036    N: Copy + Ord + Hash,
1037    Ty: EdgeType,
1038{
1039    type Map = HashSet<N>;
1040    fn visit_map(&self) -> HashSet<N> {
1041        HashSet::with_capacity(self.node_count())
1042    }
1043    fn reset_map(&self, map: &mut Self::Map) {
1044        map.clear();
1045    }
1046}
1047
1048impl<N, E, Ty> visit::GraphProp for GraphMap<N, E, Ty>
1049where
1050    N: NodeTrait,
1051    Ty: EdgeType,
1052{
1053    type EdgeType = Ty;
1054}
1055
1056impl<'a, N, E, Ty> visit::IntoNodeReferences for &'a GraphMap<N, E, Ty>
1057where
1058    N: NodeTrait,
1059    Ty: EdgeType,
1060{
1061    type NodeRef = (N, &'a N);
1062    type NodeReferences = NodeReferences<'a, N, E, Ty>;
1063    fn node_references(self) -> Self::NodeReferences {
1064        NodeReferences {
1065            iter: self.nodes.iter(),
1066            ty: self.ty,
1067            edge_ty: PhantomData,
1068        }
1069    }
1070}
1071
1072impl<'a, N, E: 'a, Ty> visit::IntoNodeIdentifiers for &'a GraphMap<N, E, Ty>
1073where
1074    N: NodeTrait,
1075    Ty: EdgeType,
1076{
1077    type NodeIdentifiers = NodeIdentifiers<'a, N, E, Ty>;
1078
1079    fn node_identifiers(self) -> Self::NodeIdentifiers {
1080        NodeIdentifiers {
1081            iter: self.nodes.iter(),
1082            ty: self.ty,
1083            edge_ty: PhantomData,
1084        }
1085    }
1086}
1087
1088impl<N, E, Ty> visit::NodeCount for GraphMap<N, E, Ty>
1089where
1090    N: NodeTrait,
1091    Ty: EdgeType,
1092{
1093    fn node_count(&self) -> usize {
1094        (*self).node_count()
1095    }
1096}
1097
1098impl<N, E, Ty> visit::NodeIndexable for GraphMap<N, E, Ty>
1099where
1100    N: NodeTrait,
1101    Ty: EdgeType,
1102{
1103    fn node_bound(&self) -> usize {
1104        self.node_count()
1105    }
1106    fn to_index(&self, ix: Self::NodeId) -> usize {
1107        let (i, _, _) = self.nodes.get_full(&ix).unwrap();
1108        i
1109    }
1110    fn from_index(&self, ix: usize) -> Self::NodeId {
1111        assert!(
1112            ix < self.nodes.len(),
1113            "The requested index {} is out-of-bounds.",
1114            ix
1115        );
1116        let (&key, _) = self.nodes.get_index(ix).unwrap();
1117        key
1118    }
1119}
1120
1121impl<N, E, Ty> visit::NodeCompactIndexable for GraphMap<N, E, Ty>
1122where
1123    N: NodeTrait,
1124    Ty: EdgeType,
1125{
1126}
1127
1128impl<'a, N: 'a, E, Ty> visit::IntoNeighbors for &'a GraphMap<N, E, Ty>
1129where
1130    N: Copy + Ord + Hash,
1131    Ty: EdgeType,
1132{
1133    type Neighbors = Neighbors<'a, N, Ty>;
1134    fn neighbors(self, n: Self::NodeId) -> Self::Neighbors {
1135        self.neighbors(n)
1136    }
1137}
1138
1139impl<'a, N: 'a, E, Ty> visit::IntoNeighborsDirected for &'a GraphMap<N, E, Ty>
1140where
1141    N: Copy + Ord + Hash,
1142    Ty: EdgeType,
1143{
1144    type NeighborsDirected = NeighborsDirected<'a, N, Ty>;
1145    fn neighbors_directed(self, n: N, dir: Direction) -> Self::NeighborsDirected {
1146        self.neighbors_directed(n, dir)
1147    }
1148}
1149
1150impl<N, E, Ty> visit::EdgeIndexable for GraphMap<N, E, Ty>
1151where
1152    N: NodeTrait,
1153    Ty: EdgeType,
1154{
1155    fn edge_bound(&self) -> usize {
1156        self.edge_count()
1157    }
1158
1159    fn to_index(&self, ix: Self::EdgeId) -> usize {
1160        let (i, _, _) = self.edges.get_full(&ix).unwrap();
1161        i
1162    }
1163
1164    fn from_index(&self, ix: usize) -> Self::EdgeId {
1165        assert!(
1166            ix < self.edges.len(),
1167            "The requested index {} is out-of-bounds.",
1168            ix
1169        );
1170        let (&key, _) = self.edges.get_index(ix).unwrap();
1171        key
1172    }
1173}
1174
1175impl<'a, N: 'a, E: 'a, Ty> visit::IntoEdges for &'a GraphMap<N, E, Ty>
1176where
1177    N: NodeTrait,
1178    Ty: EdgeType,
1179{
1180    type Edges = Edges<'a, N, E, Ty>;
1181    fn edges(self, a: Self::NodeId) -> Self::Edges {
1182        self.edges(a)
1183    }
1184}
1185
1186impl<'a, N: 'a, E: 'a, Ty> visit::IntoEdgesDirected for &'a GraphMap<N, E, Ty>
1187where
1188    N: NodeTrait,
1189    Ty: EdgeType,
1190{
1191    type EdgesDirected = EdgesDirected<'a, N, E, Ty>;
1192    fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected {
1193        self.edges_directed(a, dir)
1194    }
1195}
1196
1197impl<'a, N: 'a, E: 'a, Ty> visit::IntoEdgeReferences for &'a GraphMap<N, E, Ty>
1198where
1199    N: NodeTrait,
1200    Ty: EdgeType,
1201{
1202    type EdgeRef = (N, N, &'a E);
1203    type EdgeReferences = AllEdges<'a, N, E, Ty>;
1204    fn edge_references(self) -> Self::EdgeReferences {
1205        self.all_edges()
1206    }
1207}
1208
1209impl<N, E, Ty> visit::EdgeCount for GraphMap<N, E, Ty>
1210where
1211    N: NodeTrait,
1212    Ty: EdgeType,
1213{
1214    #[inline]
1215    fn edge_count(&self) -> usize {
1216        self.edge_count()
1217    }
1218}
1219
1220/// The `GraphMap` keeps an adjacency matrix internally.
1221impl<N, E, Ty> visit::GetAdjacencyMatrix for GraphMap<N, E, Ty>
1222where
1223    N: Copy + Ord + Hash,
1224    Ty: EdgeType,
1225{
1226    type AdjMatrix = ();
1227    #[inline]
1228    fn adjacency_matrix(&self) {}
1229    #[inline]
1230    fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
1231        self.contains_edge(a, b)
1232    }
1233}