1 //! Simple adjacency list.
2 use crate::data::{Build, DataMap, DataMapMut};
3 use crate::iter_format::NoPretty;
4 use crate::visit::{
5     self, EdgeCount, EdgeRef, GetAdjacencyMatrix, IntoEdgeReferences, IntoNeighbors, NodeCount,
6 };
7 use fixedbitset::FixedBitSet;
8 use std::fmt;
9 use std::ops::Range;
10 
11 #[doc(no_inline)]
12 pub use crate::graph::{DefaultIx, IndexType};
13 
14 /// Adjacency list node index type, a plain integer.
15 pub type NodeIndex<Ix = DefaultIx> = Ix;
16 
17 /// Adjacency list edge index type, a pair of integers.
18 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
19 pub struct EdgeIndex<Ix = DefaultIx>
20 where
21     Ix: IndexType,
22 {
23     /// Source of the edge.
24     from: NodeIndex<Ix>,
25     /// Index of the sucessor in the successor list.
26     successor_index: usize,
27 }
28 
29 iterator_wrap! {
30 impl (Iterator) for
31 /// An Iterator over the indices of the outgoing edges from a node.
32 ///
33 /// It does not borrow the graph during iteration.
34 #[derive(Debug, Clone)]
35 struct OutgoingEdgeIndices <Ix> where { Ix: IndexType }
36 item: EdgeIndex<Ix>,
37 iter: std::iter::Map<std::iter::Zip<Range<usize>, std::iter::Repeat<NodeIndex<Ix>>>, fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix>>,
38 }
39 
40 /// Weighted sucessor
41 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
42 struct WSuc<E, Ix: IndexType> {
43     /// Index of the sucessor.
44     suc: Ix,
45     /// Weight of the edge to `suc`.
46     weight: E,
47 }
48 
49 /// One row of the adjacency list.
50 type Row<E, Ix> = Vec<WSuc<E, Ix>>;
51 type RowIter<'a, E, Ix> = std::slice::Iter<'a, WSuc<E, Ix>>;
52 
53 iterator_wrap! {
54 impl (Iterator DoubleEndedIterator ExactSizeIterator) for
55 /// An iterator over the indices of the neighbors of a node.
56 #[derive(Debug, Clone)]
57 struct Neighbors<'a, E, Ix> where { Ix: IndexType }
58 item: NodeIndex<Ix>,
59 iter: std::iter::Map<RowIter<'a, E, Ix>, fn(&WSuc<E, Ix>) -> NodeIndex<Ix>>,
60 }
61 
62 /// A reference to an edge of the graph.
63 #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
64 pub struct EdgeReference<'a, E, Ix: IndexType> {
65     /// index of the edge
66     id: EdgeIndex<Ix>,
67     /// a reference to the corresponding item in the adjacency list
68     edge: &'a WSuc<E, Ix>,
69 }
70 
71 impl<'a, E, Ix: IndexType> Copy for EdgeReference<'a, E, Ix> {}
72 impl<'a, E, Ix: IndexType> Clone for EdgeReference<'a, E, Ix> {
clone(&self) -> Self73     fn clone(&self) -> Self {
74         *self
75     }
76 }
77 
78 impl<'a, E, Ix: IndexType> visit::EdgeRef for EdgeReference<'a, E, Ix> {
79     type NodeId = NodeIndex<Ix>;
80     type EdgeId = EdgeIndex<Ix>;
81     type Weight = E;
source(&self) -> Self::NodeId82     fn source(&self) -> Self::NodeId {
83         self.id.from
84     }
target(&self) -> Self::NodeId85     fn target(&self) -> Self::NodeId {
86         self.edge.suc
87     }
id(&self) -> Self::EdgeId88     fn id(&self) -> Self::EdgeId {
89         self.id
90     }
weight(&self) -> &Self::Weight91     fn weight(&self) -> &Self::Weight {
92         &self.edge.weight
93     }
94 }
95 
96 #[derive(Debug, Clone)]
97 pub struct EdgeIndices<'a, E, Ix: IndexType> {
98     rows: std::iter::Enumerate<std::slice::Iter<'a, Row<E, Ix>>>,
99     row_index: usize,
100     row_len: usize,
101     cur: usize,
102 }
103 
104 impl<'a, E, Ix: IndexType> Iterator for EdgeIndices<'a, E, Ix> {
105     type Item = EdgeIndex<Ix>;
next(&mut self) -> Option<EdgeIndex<Ix>>106     fn next(&mut self) -> Option<EdgeIndex<Ix>> {
107         loop {
108             if self.cur < self.row_len {
109                 let res = self.cur;
110                 self.cur += 1;
111                 return Some(EdgeIndex {
112                     from: Ix::new(self.row_index),
113                     successor_index: res,
114                 });
115             } else {
116                 match self.rows.next() {
117                     Some((index, row)) => {
118                         self.row_index = index;
119                         self.cur = 0;
120                         self.row_len = row.len();
121                     }
122                     None => return None,
123                 }
124             }
125         }
126     }
127 }
128 
129 iterator_wrap! {
130     impl (Iterator DoubleEndedIterator ExactSizeIterator) for
131     /// An iterator over all node indices in the graph.
132     #[derive(Debug, Clone)]
133     struct NodeIndices <Ix> where {}
134     item: Ix,
135     iter: std::iter::Map<Range<usize>, fn(usize) -> Ix>,
136 }
137 
138 /// An adjacency list with labeled edges.
139 ///
140 /// Can be interpreted as a directed graph
141 /// with unweighted nodes.
142 ///
143 /// This is the most simple adjacency list you can imagine. [`Graph`](../graph/struct.Graph.html), in contrast,
144 /// maintains both the list of successors and predecessors for each node,
145 /// which is a different trade-off.
146 ///
147 /// Allows parallel edges and self-loops.
148 ///
149 /// This data structure is append-only (except for [`clear`](#method.clear)), so indices
150 /// returned at some point for a given graph will stay valid with this same
151 /// graph until it is dropped or [`clear`](#method.clear) is called.
152 ///
153 /// Space consumption: **O(|E|)**.
154 #[derive(Clone, Default)]
155 pub struct List<E, Ix = DefaultIx>
156 where
157     Ix: IndexType,
158 {
159     suc: Vec<Row<E, Ix>>,
160 }
161 
162 impl<E, Ix: IndexType> List<E, Ix> {
163     /// Creates a new, empty adjacency list.
new() -> List<E, Ix>164     pub fn new() -> List<E, Ix> {
165         List { suc: Vec::new() }
166     }
167 
168     /// Creates a new, empty adjacency list tailored for `nodes` nodes.
with_capacity(nodes: usize) -> List<E, Ix>169     pub fn with_capacity(nodes: usize) -> List<E, Ix> {
170         List {
171             suc: Vec::with_capacity(nodes),
172         }
173     }
174 
175     /// Removes all nodes and edges from the list.
clear(&mut self)176     pub fn clear(&mut self) {
177         self.suc.clear()
178     }
179 
180     /// Returns the number of edges in the list
181     ///
182     /// Computes in **O(|V|)** time.
edge_count(&self) -> usize183     pub fn edge_count(&self) -> usize {
184         self.suc.iter().map(|x| x.len()).sum()
185     }
186 
187     /// Adds a new node to the list. This allocates a new `Vec` and then should
188     /// run in amortized **O(1)** time.
add_node(&mut self) -> NodeIndex<Ix>189     pub fn add_node(&mut self) -> NodeIndex<Ix> {
190         let i = self.suc.len();
191         self.suc.push(Vec::new());
192         Ix::new(i)
193     }
194 
195     /// Adds a new node to the list. This allocates a new `Vec` and then should
196     /// run in amortized **O(1)** time.
add_node_with_capacity(&mut self, successors: usize) -> NodeIndex<Ix>197     pub fn add_node_with_capacity(&mut self, successors: usize) -> NodeIndex<Ix> {
198         let i = self.suc.len();
199         self.suc.push(Vec::with_capacity(successors));
200         Ix::new(i)
201     }
202 
203     /// Adds a new node to the list by giving its list of successors and the corresponding
204     /// weigths.
add_node_from_edges<I: Iterator<Item = (NodeIndex<Ix>, E)>>( &mut self, edges: I, ) -> NodeIndex<Ix>205     pub fn add_node_from_edges<I: Iterator<Item = (NodeIndex<Ix>, E)>>(
206         &mut self,
207         edges: I,
208     ) -> NodeIndex<Ix> {
209         let i = self.suc.len();
210         self.suc
211             .push(edges.map(|(suc, weight)| WSuc { suc, weight }).collect());
212         Ix::new(i)
213     }
214 
215     /// Add an edge from `a` to `b` to the graph, with its associated
216     /// data `weight`.
217     ///
218     /// Return the index of the new edge.
219     ///
220     /// Computes in **O(1)** time.
221     ///
222     /// **Panics** if the source node does not exist.<br>
223     ///
224     /// **Note:** `List` allows adding parallel (“duplicate”) edges. If you want
225     /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix>226     pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
227         if b.index() >= self.suc.len() {
228             panic!(
229                 "{} is not a valid node index for a {} nodes adjacency list",
230                 b.index(),
231                 self.suc.len()
232             );
233         }
234         let row = &mut self.suc[a.index()];
235         let rank = row.len();
236         row.push(WSuc { suc: b, weight });
237         EdgeIndex {
238             from: a,
239             successor_index: rank,
240         }
241     }
242 
get_edge(&self, e: EdgeIndex<Ix>) -> Option<&WSuc<E, Ix>>243     fn get_edge(&self, e: EdgeIndex<Ix>) -> Option<&WSuc<E, Ix>> {
244         self.suc
245             .get(e.from.index())
246             .and_then(|row| row.get(e.successor_index))
247     }
248 
get_edge_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut WSuc<E, Ix>>249     fn get_edge_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut WSuc<E, Ix>> {
250         self.suc
251             .get_mut(e.from.index())
252             .and_then(|row| row.get_mut(e.successor_index))
253     }
254 
255     /// Accesses the source and target of edge `e`
256     ///
257     /// Computes in **O(1)**
edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)>258     pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
259         self.get_edge(e).map(|x| (e.from, x.suc))
260     }
261 
edge_indices_from(&self, a: NodeIndex<Ix>) -> OutgoingEdgeIndices<Ix>262     pub fn edge_indices_from(&self, a: NodeIndex<Ix>) -> OutgoingEdgeIndices<Ix> {
263         let proj: fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix> =
264             |(successor_index, from)| EdgeIndex {
265                 from,
266                 successor_index,
267             };
268         let iter = (0..(self.suc[a.index()].len()))
269             .zip(std::iter::repeat(a))
270             .map(proj);
271         OutgoingEdgeIndices { iter }
272     }
273 
274     /// Lookups whether there is an edge from `a` to `b`.
275     ///
276     /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool277     pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
278         match self.suc.get(a.index()) {
279             None => false,
280             Some(row) => row.iter().any(|x| x.suc == b),
281         }
282     }
283 
284     /// Lookups whether there is an edge from `a` to `b`.
285     ///
286     /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>>287     pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
288         self.suc.get(a.index()).and_then(|row| {
289             row.iter()
290                 .enumerate()
291                 .find(|(_, x)| x.suc == b)
292                 .map(|(i, _)| EdgeIndex {
293                     from: a,
294                     successor_index: i,
295                 })
296         })
297     }
298 
299     /// Returns an iterator over all node indices of the graph.
300     ///
301     /// Consuming the whole iterator take **O(|V|)**.
node_indices(&self) -> NodeIndices<Ix>302     pub fn node_indices(&self) -> NodeIndices<Ix> {
303         NodeIndices {
304             iter: (0..self.suc.len()).map(Ix::new),
305         }
306     }
307 
308     /// Returns an iterator over all edge indices of the graph.
309     ///
310     /// Consuming the whole iterator take **O(|V| + |E|)**.
edge_indices(&self) -> EdgeIndices<E, Ix>311     pub fn edge_indices(&self) -> EdgeIndices<E, Ix> {
312         EdgeIndices {
313             rows: self.suc.iter().enumerate(),
314             row_index: 0,
315             row_len: 0,
316             cur: 0,
317         }
318     }
319 }
320 
321 /// A very simple adjacency list with no node or label weights.
322 pub type UnweightedList<Ix> = List<(), Ix>;
323 
324 impl<E, Ix: IndexType> Build for List<E, Ix> {
325     /// Adds a new node to the list. This allocates a new `Vec` and then should
326     /// run in amortized **O(1)** time.
add_node(&mut self, _weight: ()) -> NodeIndex<Ix>327     fn add_node(&mut self, _weight: ()) -> NodeIndex<Ix> {
328         self.add_node()
329     }
330 
331     /// Add an edge from `a` to `b` to the graph, with its associated
332     /// data `weight`.
333     ///
334     /// Return the index of the new edge.
335     ///
336     /// Computes in **O(1)** time.
337     ///
338     /// **Panics** if the source node does not exist.<br>
339     ///
340     /// **Note:** `List` allows adding parallel (“duplicate”) edges. If you want
341     /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> Option<EdgeIndex<Ix>>342     fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> Option<EdgeIndex<Ix>> {
343         Some(self.add_edge(a, b, weight))
344     }
345 
346     /// Updates or adds an edge from `a` to `b` to the graph, with its associated
347     /// data `weight`.
348     ///
349     /// Return the index of the new edge.
350     ///
351     /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
352     ///
353     /// **Panics** if the source node does not exist.<br>
update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix>354     fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
355         let row = &mut self.suc[a.index()];
356         for (i, info) in row.iter_mut().enumerate() {
357             if info.suc == b {
358                 info.weight = weight;
359                 return EdgeIndex {
360                     from: a,
361                     successor_index: i,
362                 };
363             }
364         }
365         let rank = row.len();
366         row.push(WSuc { suc: b, weight });
367         EdgeIndex {
368             from: a,
369             successor_index: rank,
370         }
371     }
372 }
373 
374 impl<'a, E, Ix> fmt::Debug for EdgeReferences<'a, E, Ix>
375 where
376     E: fmt::Debug,
377     Ix: IndexType,
378 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result379     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
380         let mut edge_list = f.debug_list();
381         let iter: Self = self.clone();
382         for e in iter {
383             if std::mem::size_of::<E>() != 0 {
384                 edge_list.entry(&(
385                     NoPretty((e.source().index(), e.target().index())),
386                     e.weight(),
387                 ));
388             } else {
389                 edge_list.entry(&NoPretty((e.source().index(), e.target().index())));
390             }
391         }
392         edge_list.finish()
393     }
394 }
395 
396 impl<E, Ix> fmt::Debug for List<E, Ix>
397 where
398     E: fmt::Debug,
399     Ix: IndexType,
400 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result401     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
402         let mut fmt_struct = f.debug_struct("adj::List");
403         fmt_struct.field("node_count", &self.node_count());
404         fmt_struct.field("edge_count", &self.edge_count());
405         if self.edge_count() > 0 {
406             fmt_struct.field("edges", &self.edge_references());
407         }
408         fmt_struct.finish()
409     }
410 }
411 
412 impl<E, Ix> visit::GraphBase for List<E, Ix>
413 where
414     Ix: IndexType,
415 {
416     type NodeId = NodeIndex<Ix>;
417     type EdgeId = EdgeIndex<Ix>;
418 }
419 
420 impl<E, Ix> visit::Visitable for List<E, Ix>
421 where
422     Ix: IndexType,
423 {
424     type Map = FixedBitSet;
visit_map(&self) -> FixedBitSet425     fn visit_map(&self) -> FixedBitSet {
426         FixedBitSet::with_capacity(self.node_count())
427     }
reset_map(&self, map: &mut Self::Map)428     fn reset_map(&self, map: &mut Self::Map) {
429         map.clear();
430         map.grow(self.node_count());
431     }
432 }
433 
434 impl<'a, E, Ix: IndexType> visit::IntoNodeIdentifiers for &'a List<E, Ix> {
435     type NodeIdentifiers = NodeIndices<Ix>;
node_identifiers(self) -> NodeIndices<Ix>436     fn node_identifiers(self) -> NodeIndices<Ix> {
437         self.node_indices()
438     }
439 }
440 
441 impl<Ix: IndexType> visit::NodeRef for NodeIndex<Ix> {
442     type NodeId = NodeIndex<Ix>;
443     type Weight = ();
id(&self) -> Self::NodeId444     fn id(&self) -> Self::NodeId {
445         *self
446     }
weight(&self) -> &Self::Weight447     fn weight(&self) -> &Self::Weight {
448         &()
449     }
450 }
451 
452 impl<'a, Ix: IndexType, E> visit::IntoNodeReferences for &'a List<E, Ix> {
453     type NodeRef = NodeIndex<Ix>;
454     type NodeReferences = NodeIndices<Ix>;
node_references(self) -> Self::NodeReferences455     fn node_references(self) -> Self::NodeReferences {
456         self.node_indices()
457     }
458 }
459 
460 impl<E, Ix: IndexType> visit::Data for List<E, Ix> {
461     type NodeWeight = ();
462     type EdgeWeight = E;
463 }
464 
465 impl<'a, E, Ix: IndexType> IntoNeighbors for &'a List<E, Ix> {
466     type Neighbors = Neighbors<'a, E, Ix>;
467     /// Returns an iterator of all nodes with an edge starting from `a`.
468     /// Panics if `a` is out of bounds.
469     /// Use [`List::edge_indices_from`] instead if you do not want to borrow the adjacency list while
470     /// iterating.
neighbors(self, a: NodeIndex<Ix>) -> Self::Neighbors471     fn neighbors(self, a: NodeIndex<Ix>) -> Self::Neighbors {
472         let proj: fn(&WSuc<E, Ix>) -> NodeIndex<Ix> = |x| x.suc;
473         let iter = self.suc[a.index()].iter().map(proj);
474         Neighbors { iter }
475     }
476 }
477 
478 type SomeIter<'a, E, Ix> = std::iter::Map<
479     std::iter::Zip<std::iter::Enumerate<RowIter<'a, E, Ix>>, std::iter::Repeat<Ix>>,
480     fn(((usize, &'a WSuc<E, Ix>), Ix)) -> EdgeReference<'a, E, Ix>,
481 >;
482 
483 iterator_wrap! {
484 impl (Iterator) for
485 /// An iterator over the [`EdgeReference`] of all the edges of the graph.
486 struct EdgeReferences<'a, E, Ix> where { Ix: IndexType }
487 item: EdgeReference<'a, E, Ix>,
488 iter: std::iter::FlatMap<
489     std::iter::Enumerate<
490         std::slice::Iter<'a, Row<E, Ix>>
491     >,
492     SomeIter<'a, E, Ix>,
493     fn(
494         (usize, &'a Vec<WSuc<E, Ix>>)
495     ) -> SomeIter<'a, E, Ix>,
496 >,
497 }
498 
499 impl<'a, E, Ix: IndexType> Clone for EdgeReferences<'a, E, Ix> {
clone(&self) -> Self500     fn clone(&self) -> Self {
501         EdgeReferences {
502             iter: self.iter.clone(),
503         }
504     }
505 }
506 
proj1<E, Ix: IndexType>( ((successor_index, edge), from): ((usize, &WSuc<E, Ix>), Ix), ) -> EdgeReference<E, Ix>507 fn proj1<E, Ix: IndexType>(
508     ((successor_index, edge), from): ((usize, &WSuc<E, Ix>), Ix),
509 ) -> EdgeReference<E, Ix> {
510     let id = EdgeIndex {
511         from,
512         successor_index,
513     };
514     EdgeReference { id, edge }
515 }
proj2<E, Ix: IndexType>((row_index, row): (usize, &Vec<WSuc<E, Ix>>)) -> SomeIter<E, Ix>516 fn proj2<E, Ix: IndexType>((row_index, row): (usize, &Vec<WSuc<E, Ix>>)) -> SomeIter<E, Ix> {
517     row.iter()
518         .enumerate()
519         .zip(std::iter::repeat(Ix::new(row_index)))
520         .map(proj1 as _)
521 }
522 
523 impl<'a, Ix: IndexType, E> visit::IntoEdgeReferences for &'a List<E, Ix> {
524     type EdgeRef = EdgeReference<'a, E, Ix>;
525     type EdgeReferences = EdgeReferences<'a, E, Ix>;
edge_references(self) -> Self::EdgeReferences526     fn edge_references(self) -> Self::EdgeReferences {
527         let iter = self.suc.iter().enumerate().flat_map(proj2 as _);
528         EdgeReferences { iter }
529     }
530 }
531 
532 iterator_wrap! {
533 impl (Iterator) for
534 /// Iterator over the [`EdgeReference`] of the outgoing edges from a node.
535 #[derive(Debug, Clone)]
536 struct OutgoingEdgeReferences<'a, E, Ix> where { Ix: IndexType }
537 item: EdgeReference<'a, E, Ix>,
538 iter: SomeIter<'a, E, Ix>,
539 }
540 
541 impl<'a, Ix: IndexType, E> visit::IntoEdges for &'a List<E, Ix> {
542     type Edges = OutgoingEdgeReferences<'a, E, Ix>;
edges(self, a: Self::NodeId) -> Self::Edges543     fn edges(self, a: Self::NodeId) -> Self::Edges {
544         let iter = self.suc[a.index()]
545             .iter()
546             .enumerate()
547             .zip(std::iter::repeat(a))
548             .map(proj1 as _);
549         OutgoingEdgeReferences { iter }
550     }
551 }
552 
553 impl<E, Ix: IndexType> visit::GraphProp for List<E, Ix> {
554     type EdgeType = crate::Directed;
is_directed(&self) -> bool555     fn is_directed(&self) -> bool {
556         true
557     }
558 }
559 
560 impl<E, Ix: IndexType> NodeCount for List<E, Ix> {
561     /// Returns the number of nodes in the list
562     ///
563     /// Computes in **O(1)** time.
node_count(&self) -> usize564     fn node_count(&self) -> usize {
565         self.suc.len()
566     }
567 }
568 
569 impl<E, Ix: IndexType> EdgeCount for List<E, Ix> {
570     /// Returns the number of edges in the list
571     ///
572     /// Computes in **O(|V|)** time.
edge_count(&self) -> usize573     fn edge_count(&self) -> usize {
574         List::edge_count(self)
575     }
576 }
577 
578 impl<E, Ix: IndexType> visit::NodeIndexable for List<E, Ix> {
node_bound(&self) -> usize579     fn node_bound(&self) -> usize {
580         self.node_count()
581     }
582     #[inline]
to_index(&self, a: Self::NodeId) -> usize583     fn to_index(&self, a: Self::NodeId) -> usize {
584         a.index()
585     }
586     #[inline]
from_index(&self, i: usize) -> Self::NodeId587     fn from_index(&self, i: usize) -> Self::NodeId {
588         Ix::new(i)
589     }
590 }
591 
592 impl<E, Ix: IndexType> visit::NodeCompactIndexable for List<E, Ix> {}
593 
594 impl<E, Ix: IndexType> DataMap for List<E, Ix> {
node_weight(&self, n: Self::NodeId) -> Option<&()>595     fn node_weight(&self, n: Self::NodeId) -> Option<&()> {
596         if n.index() < self.suc.len() {
597             Some(&())
598         } else {
599             None
600         }
601     }
602 
603     /// Accesses the weight of edge `e`
604     ///
605     /// Computes in **O(1)**
edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E>606     fn edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E> {
607         self.get_edge(e).map(|x| &x.weight)
608     }
609 }
610 
611 impl<E, Ix: IndexType> DataMapMut for List<E, Ix> {
node_weight_mut(&mut self, n: Self::NodeId) -> Option<&mut ()>612     fn node_weight_mut(&mut self, n: Self::NodeId) -> Option<&mut ()> {
613         if n.index() < self.suc.len() {
614             // A hack to produce a &'static mut ()
615             // It does not actually allocate according to godbolt
616             let b = Box::new(());
617             Some(Box::leak(b))
618         } else {
619             None
620         }
621     }
622     /// Accesses the weight of edge `e`
623     ///
624     /// Computes in **O(1)**
edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E>625     fn edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E> {
626         self.get_edge_mut(e).map(|x| &mut x.weight)
627     }
628 }
629 
630 /// The adjacency matrix for **List** is a bitmap that's computed by
631 /// `.adjacency_matrix()`.
632 impl<E, Ix> GetAdjacencyMatrix for List<E, Ix>
633 where
634     Ix: IndexType,
635 {
636     type AdjMatrix = FixedBitSet;
637 
adjacency_matrix(&self) -> FixedBitSet638     fn adjacency_matrix(&self) -> FixedBitSet {
639         let n = self.node_count();
640         let mut matrix = FixedBitSet::with_capacity(n * n);
641         for edge in self.edge_references() {
642             let i = edge.source().index() * n + edge.target().index();
643             matrix.put(i);
644 
645             let j = edge.source().index() + n * edge.target().index();
646             matrix.put(j);
647         }
648         matrix
649     }
650 
is_adjacent(&self, matrix: &FixedBitSet, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool651     fn is_adjacent(&self, matrix: &FixedBitSet, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
652         let n = self.edge_count();
653         let index = n * a.index() + b.index();
654         matrix.contains(index)
655     }
656 }
657