1use fixedbitset::FixedBitSet;
3use crate::iter_format::NoPretty;
4use core::fmt;
5use core::ops::Range;
6use crate::visit::{self, EdgeRef, IntoEdgeReferences, IntoNeighbors, NodeCount};
7use crate::data::{Build, DataMap, DataMapMut};
8use alloc::{vec::Vec, boxed::Box};
9
10#[doc(no_inline)]
11pub use crate::graph::{DefaultIx, IndexType};
12
13pub type NodeIndex<Ix = DefaultIx> = Ix;
15
16#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
18pub struct EdgeIndex<Ix = DefaultIx>
19where
20 Ix: IndexType,
21{
22 from: NodeIndex<Ix>,
24 successor_index: usize,
26}
27
28iterator_wrap! {
29impl (Iterator) for
30struct OutgoingEdgeIndices <Ix> where { Ix: IndexType }
34item: EdgeIndex<Ix>,
35iter: core::iter::Map<core::iter::Zip<Range<usize>, core::iter::Repeat<NodeIndex<Ix>>>, fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix>>,
36}
37
38#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
40struct WSuc<E, Ix: IndexType> {
41 suc: Ix,
43 weight: E,
45}
46
47type Row<E, Ix> = Vec<WSuc<E, Ix>>;
49type RowIter<'a, E, Ix> = core::slice::Iter<'a, WSuc<E, Ix>>;
50
51iterator_wrap! {
52impl (Iterator DoubleEndedIterator ExactSizeIterator) for
53struct Neighbors<'a, E, Ix> where { Ix: IndexType }
55item: NodeIndex<Ix>,
56iter: core::iter::Map<RowIter<'a, E, Ix>, fn(&WSuc<E, Ix>) -> NodeIndex<Ix>>,
57}
58
59#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
61pub struct EdgeReference<'a, E, Ix: IndexType> {
62 id: EdgeIndex<Ix>,
64 edge: &'a WSuc<E, Ix>,
66}
67
68impl<'a, E, Ix: IndexType> Copy for EdgeReference<'a, E, Ix> {}
69impl<'a, E, Ix: IndexType> Clone for EdgeReference<'a, E, Ix> {
70 fn clone(&self) -> Self {
71 EdgeReference {
72 id: self.id,
73 edge: self.edge,
74 }
75 }
76}
77
78impl<'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;
82 fn source(&self) -> Self::NodeId {
83 self.id.from
84 }
85 fn target(&self) -> Self::NodeId {
86 self.edge.suc
87 }
88 fn id(&self) -> Self::EdgeId {
89 self.id
90 }
91 fn weight(&self) -> &Self::Weight {
92 &self.edge.weight
93 }
94}
95
96pub struct EdgeIndices<'a, E, Ix: IndexType> {
97 rows: core::iter::Enumerate<core::slice::Iter<'a, Row<E, Ix>>>,
98 row_index: usize,
99 row_len: usize,
100 cur: usize,
101}
102
103impl<'a, E, Ix: IndexType> Iterator for EdgeIndices<'a, E, Ix> {
104 type Item = EdgeIndex<Ix>;
105 fn next(&mut self) -> Option<EdgeIndex<Ix>> {
106 loop {
107 if self.cur < self.row_len {
108 let res = self.cur;
109 self.cur += 1;
110 return Some(EdgeIndex {
111 from: Ix::new(self.row_index),
112 successor_index: res,
113 });
114 } else {
115 match self.rows.next() {
116 Some((index, row)) => {
117 self.row_index = index;
118 self.cur = 0;
119 self.row_len = row.len();
120 }
121 None => return None,
122 }
123 }
124 }
125 }
126}
127
128iterator_wrap! {
129 impl (Iterator DoubleEndedIterator ExactSizeIterator) for
130 struct NodeIndices <Ix> where {}
132 item: Ix,
133 iter: core::iter::Map<Range<usize>, fn(usize) -> Ix>,
134}
135
136#[derive(Clone, Default)]
153pub struct List<E, Ix = DefaultIx>
154where
155 Ix: IndexType,
156{
157 suc: Vec<Row<E, Ix>>,
158}
159
160impl<E, Ix: IndexType> List<E, Ix> {
161 pub fn new() -> List<E, Ix> {
163 List { suc: Vec::new() }
164 }
165
166 pub fn with_capacity(nodes: usize) -> List<E, Ix> {
168 List {
169 suc: Vec::with_capacity(nodes),
170 }
171 }
172
173 pub fn clear(&mut self) {
175 self.suc.clear()
176 }
177
178 pub fn edge_count(&self) -> usize {
182 self.suc.iter().map(|x| x.len()).sum()
183 }
184
185 pub fn add_node(&mut self) -> NodeIndex<Ix> {
188 let i = self.suc.len();
189 self.suc.push(Vec::new());
190 Ix::new(i)
191 }
192
193 pub fn add_node_with_capacity(&mut self, successors: usize) -> NodeIndex<Ix> {
196 let i = self.suc.len();
197 self.suc.push(Vec::with_capacity(successors));
198 Ix::new(i)
199 }
200
201 pub fn add_node_from_edges<I: Iterator<Item = (NodeIndex<Ix>, E)>>(
204 &mut self,
205 edges: I,
206 ) -> NodeIndex<Ix> {
207 let i = self.suc.len();
208 self.suc
209 .push(edges.map(|(suc, weight)| WSuc { suc, weight }).collect());
210 Ix::new(i)
211 }
212
213 pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
225 if b.index() >= self.suc.len() {
226 panic!("{} is not a valid node index for a {} nodes adjacency list", b.index(), self.suc.len());
227 }
228 let row = &mut self.suc[a.index()];
229 let rank = row.len();
230 row.push(WSuc { suc: b, weight });
231 EdgeIndex {
232 from: a,
233 successor_index: rank,
234 }
235 }
236
237 fn get_edge(&self, e: EdgeIndex<Ix>) -> Option<&WSuc<E, Ix>> {
238 self.suc
239 .get(e.from.index())
240 .and_then(|row| row.get(e.successor_index))
241 }
242
243 fn get_edge_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut WSuc<E, Ix>> {
244 self.suc
245 .get_mut(e.from.index())
246 .and_then(|row| row.get_mut(e.successor_index))
247 }
248
249 pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
253 self.get_edge(e).map(|x| (e.from, x.suc))
254 }
255
256 pub fn edge_indices_from(&self, a: NodeIndex<Ix>) -> OutgoingEdgeIndices<Ix> {
257 let proj: fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix> =
258 |(successor_index, from)| EdgeIndex {
259 from,
260 successor_index,
261 };
262 let iter = (0..(self.suc[a.index()].len()))
263 .zip(core::iter::repeat(a))
264 .map(proj);
265 OutgoingEdgeIndices { iter }
266 }
267
268 pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
272 match self.suc.get(a.index()) {
273 None => false,
274 Some(row) => row.iter().any(|x| x.suc == b),
275 }
276 }
277
278 pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
282 self.suc.get(a.index()).and_then(|row| {
283 row.iter()
284 .enumerate()
285 .find(|(_, x)| x.suc == b)
286 .map(|(i, _)| EdgeIndex {
287 from: a,
288 successor_index: i,
289 })
290 })
291 }
292
293 pub fn node_indices(&self) -> NodeIndices<Ix> {
297 NodeIndices {
298 iter: (0..self.suc.len()).map(Ix::new),
299 }
300 }
301
302 pub fn edge_indices(&self) -> EdgeIndices<E, Ix> {
306 EdgeIndices {
307 rows: self.suc.iter().enumerate(),
308 row_index: 0,
309 row_len: 0,
310 cur: 0,
311 }
312 }
313}
314
315
316pub type UnweightedList<Ix> = List<(), Ix>;
318
319
320impl<E, Ix: IndexType> Build for List<E, Ix> {
321 fn add_node(&mut self, _weight: ()) -> NodeIndex<Ix> {
324 self.add_node()
325 }
326
327 fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> Option<EdgeIndex<Ix>> {
339 Some(self.add_edge(a, b, weight))
340 }
341
342 fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
351 let row = &mut self.suc[a.index()];
352 for (i, info) in row.iter_mut().enumerate() {
353 if info.suc == b {
354 info.weight = weight;
355 return EdgeIndex {
356 from: a,
357 successor_index: i,
358 };
359 }
360 }
361 let rank = row.len();
362 row.push(WSuc { suc: b, weight });
363 EdgeIndex {
364 from: a,
365 successor_index: rank,
366 }
367 }
368}
369
370
371
372impl<'a, E, Ix> fmt::Debug for EdgeReferences<'a, E, Ix>
373where
374 E: fmt::Debug,
375 Ix: IndexType,
376{
377 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378 let mut edge_list = f.debug_list();
379 let iter: Self = self.clone();
380 for e in iter {
381 if core::mem::size_of::<E>() != 0 {
382 edge_list.entry(&(
383 NoPretty((e.source().index(), e.target().index())),
384 e.weight(),
385 ));
386 } else {
387 edge_list.entry(&NoPretty((e.source().index(), e.target().index())));
388 }
389 }
390 edge_list.finish()
391 }
392}
393
394impl<E, Ix> fmt::Debug for List<E, Ix>
395where
396 E: fmt::Debug,
397 Ix: IndexType,
398{
399 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
400 let mut fmt_struct = f.debug_struct("adj::List");
401 fmt_struct.field("node_count", &self.node_count());
402 fmt_struct.field("edge_count", &self.edge_count());
403 if self.edge_count() > 0 {
404 fmt_struct.field("edges", &self.edge_references());
405 }
406 fmt_struct.finish()
407 }
408}
409
410impl<E, Ix> visit::GraphBase for List<E, Ix>
411where
412 Ix: IndexType,
413{
414 type NodeId = NodeIndex<Ix>;
415 type EdgeId = EdgeIndex<Ix>;
416}
417
418impl<E, Ix> visit::Visitable for List<E, Ix>
419where
420 Ix: IndexType,
421{
422 type Map = FixedBitSet;
423 fn visit_map(&self) -> FixedBitSet {
424 FixedBitSet::with_capacity(self.node_count())
425 }
426 fn reset_map(&self, map: &mut Self::Map) {
427 map.clear();
428 map.grow(self.node_count());
429 }
430}
431
432impl<'a, E, Ix: IndexType> visit::IntoNodeIdentifiers for &'a List<E, Ix> {
433 type NodeIdentifiers = NodeIndices<Ix>;
434 fn node_identifiers(self) -> NodeIndices<Ix> {
435 self.node_indices()
436 }
437}
438
439impl<Ix: IndexType> visit::NodeRef for NodeIndex<Ix> {
440 type NodeId = NodeIndex<Ix>;
441 type Weight = ();
442 fn id(&self) -> Self::NodeId {
443 *self
444 }
445 fn weight(&self) -> &Self::Weight {
446 &()
447 }
448}
449
450impl<'a, Ix: IndexType, E> visit::IntoNodeReferences for &'a List<E, Ix> {
451 type NodeRef = NodeIndex<Ix>;
452 type NodeReferences = NodeIndices<Ix>;
453 fn node_references(self) -> Self::NodeReferences {
454 self.node_indices()
455 }
456}
457
458impl<E, Ix: IndexType> visit::Data for List<E, Ix> {
459 type NodeWeight = ();
460 type EdgeWeight = E;
461}
462
463impl<'a, E, Ix: IndexType> IntoNeighbors for &'a List<E, Ix> {
464 type Neighbors = Neighbors<'a, E, Ix>;
465 fn neighbors(self, a: NodeIndex<Ix>) -> Self::Neighbors {
470 let proj: fn(&WSuc<E, Ix>) -> NodeIndex<Ix> = |x| x.suc;
471 let iter = self.suc[a.index()].iter().map(proj);
472 Neighbors { iter }
473 }
474}
475
476type SomeIter<'a, E, Ix> = core::iter::Map<
477 core::iter::Zip<core::iter::Enumerate<RowIter<'a, E, Ix>>, core::iter::Repeat<Ix>>,
478 fn(((usize, &'a WSuc<E, Ix>), Ix)) -> EdgeReference<'a, E, Ix>,
479>;
480
481iterator_wrap! {
482impl (Iterator) for
483struct EdgeReferences<'a, E, Ix> where { Ix: IndexType }
485item: EdgeReference<'a, E, Ix>,
486iter: core::iter::FlatMap<
487 core::iter::Enumerate<
488 core::slice::Iter<'a, Row<E, Ix>>
489 >,
490 SomeIter<'a, E, Ix>,
491 fn(
492 (usize, &'a Vec<WSuc<E, Ix>>)
493 ) -> SomeIter<'a, E, Ix>,
494>,
495}
496
497impl<'a, E, Ix: IndexType> Clone for EdgeReferences<'a, E, Ix> {
498 fn clone(&self) -> Self {
499 EdgeReferences {
500 iter: self.iter.clone(),
501 }
502 }
503}
504
505fn proj1<'a, E, Ix: IndexType>(
506 ((successor_index, edge), from): ((usize, &'a WSuc<E, Ix>), Ix),
507) -> EdgeReference<'a, E, Ix> {
508 let id = EdgeIndex {
509 from,
510 successor_index,
511 };
512 EdgeReference { id, edge }
513}
514fn proj2<'a, E, Ix: IndexType>(
515 (row_index, row): (usize, &'a Vec<WSuc<E, Ix>>),
516) -> SomeIter<'a, E, Ix> {
517 row.iter()
518 .enumerate()
519 .zip(core::iter::repeat(Ix::new(row_index)))
520 .map(proj1 as _)
521}
522
523impl<'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>;
526 fn edge_references(self) -> Self::EdgeReferences {
527 let iter = self.suc.iter().enumerate().flat_map(proj2 as _);
528 EdgeReferences { iter }
529 }
530}
531
532iterator_wrap! {
533impl (Iterator) for
534struct OutgoingEdgeReferences<'a, E, Ix> where { Ix: IndexType }
536item: EdgeReference<'a, E, Ix>,
537iter: SomeIter<'a, E, Ix>,
538}
539
540impl<'a, Ix: IndexType, E> visit::IntoEdges for &'a List<E, Ix> {
541 type Edges = OutgoingEdgeReferences<'a, E, Ix>;
542 fn edges(self, a: Self::NodeId) -> Self::Edges {
543 let iter = self.suc[a.index()]
544 .iter()
545 .enumerate()
546 .zip(core::iter::repeat(a))
547 .map(proj1 as _);
548 OutgoingEdgeReferences { iter }
549 }
550}
551
552impl<E, Ix: IndexType> visit::GraphProp for List<E, Ix> {
553 type EdgeType = crate::Directed;
554 fn is_directed(&self) -> bool { true }
555}
556
557impl <E, Ix: IndexType> NodeCount for List<E, Ix> {
558 fn node_count(&self) -> usize {
562 self.suc.len()
563 }
564}
565
566impl<E, Ix: IndexType> visit::NodeIndexable for List<E, Ix> {
567 fn node_bound(&self) -> usize {
568 self.node_count()
569 }
570 #[inline]
571 fn to_index(&self, a: Self::NodeId) -> usize {
572 a.index()
573 }
574 #[inline]
575 fn from_index(&self, i: usize) -> Self::NodeId {
576 Ix::new(i)
577 }
578}
579
580impl<E, Ix: IndexType> visit::NodeCompactIndexable for List<E, Ix> {}
581
582impl<E, Ix: IndexType> DataMap for List<E, Ix> {
583 fn node_weight(&self, n: Self::NodeId) -> Option<&()> {
584 if n.index() < self.suc.len() {
585 Some(&())
586 } else {
587 None
588 }
589 }
590
591 fn edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E> {
595 self.get_edge(e).map(|x| &x.weight)
596 }
597}
598
599impl<E, Ix: IndexType> DataMapMut for List<E, Ix> {
600 fn node_weight_mut(&mut self, n: Self::NodeId) -> Option<&mut ()> {
601 if n.index() < self.suc.len() {
602 let b = Box::new(());
605 Some(Box::leak(b))
606 } else {
607 None
608 }
609 }
610 fn edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E> {
614 self.get_edge_mut(e).map(|x| &mut x.weight)
615 }
616}
617