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