1use super::{Edge, Edges, FrozenGraph, Graph, IntKeyMap, Map, Node};
5use core::{fmt::Debug, iter::FusedIterator, marker::PhantomData};
6
7macro_rules! impl_drain_edges {
8 ($name:ident, $word:literal, $word2:literal, $next:ident, $unlink:ident, $node_field:ident, $other_node_field:ident) => {
9 #[doc = concat!(
10 "A draining iterator over the ", $word, " edges of a node. The iterator yields a tuple with ",
11 "the index of the ", $word, " node and the weight of the edge.\n\n"
12 )]
13 #[derive(Debug)]
16 pub struct $name<'graph, N, E, NI, EI, NM, EM>
17 where
18 NI: Copy + Eq + Debug + 'static,
19 EI: Copy + Eq + Debug + 'static,
20 NM: Map<Node<N, EI>, Key = NI>,
21 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
22 {
23 pub(super) graph: &'graph mut Graph<N, E, NI, EI, NM, EM>,
24 pub(super) next_edge_index: Option<EI>,
25 }
26
27 impl<'graph, N, E, NI, EI, NM, EM> Iterator for $name<'graph, N, E, NI, EI, NM, EM>
28 where
29 NI: Copy + Eq + Debug + 'static,
30 EI: Copy + Eq + Debug + 'static,
31 NM: Map<Node<N, EI>, Key = NI>,
32 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
33 {
34 type Item = (NI, E);
35
36 fn next(&mut self) -> Option<Self::Item> {
37 let next_edge_index = self.next_edge_index?;
38
39 let edge = self.graph.edges.map.remove(next_edge_index).unwrap();
42 self.graph.$unlink(next_edge_index, &edge);
43
44 self.next_edge_index = edge.$next;
45 self.graph.nodes[edge.$other_node_field].$next = edge.$next;
46
47 Some((edge.$node_field, edge.weight))
48 }
49 }
50
51 impl<'graph, N, E, NI, EI, NM, EM> FusedIterator
52 for $name<'graph, N, E, NI, EI, NM, EM>
53 where
54 NI: Copy + Eq + Debug + 'static,
55 EI: Copy + Eq + Debug + 'static,
56 NM: Map<Node<N, EI>, Key = NI>,
57 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
58 {
59 }
60 };
61}
62
63impl_drain_edges!(
64 DrainOutgoingEdges,
65 "outgoing",
66 "destination",
67 next_outgoing_edge,
68 unlink_edge_from_incoming_list,
69 to,
70 from
71);
72impl_drain_edges!(
73 DrainIncomingEdges,
74 "incoming",
75 "source",
76 next_incoming_edge,
77 unlink_edge_from_outgoing_list,
78 from,
79 to
80);
81
82macro_rules! impl_node_weights {
83 ($name:ident, $word:literal, $iter:ident, $item:ty, $weight:ident) => {
84 #[doc = concat!($word, " iterator over the [`Graph`]'s nodes' weights.")]
85 #[derive(Debug)]
86 pub struct $name<'graph, N, NI, EI, NM>
87 where
88 N: 'graph,
89 NI: Copy + Eq + Debug + 'static,
90 EI: Copy + Eq + Debug + 'static,
91 NM: Map<Node<N, EI>, Key = NI> + 'graph,
92 {
93 pub(super) inner: NM::$iter<'graph>,
94 }
95
96 impl<'graph, N, NI, EI, NM> Iterator for $name<'graph, N, NI, EI, NM>
97 where
98 N: 'graph,
99 NI: Copy + Eq + Debug + 'static,
100 EI: Copy + Eq + Debug + 'static,
101 NM: Map<Node<N, EI>, Key = NI> + 'graph,
102 {
103 type Item = (NM::Key, $item);
104
105 #[inline]
106 fn next(&mut self) -> Option<Self::Item> {
107 self.inner
108 .next()
109 .map(|(index, node)| (index, node.$weight()))
110 }
111
112 #[inline]
113 fn size_hint(&self) -> (usize, Option<usize>) {
114 self.inner.size_hint()
115 }
116 }
117
118 impl<'graph, N, NI, EI, NM> ExactSizeIterator for $name<'graph, N, NI, EI, NM>
119 where
120 N: 'graph,
121 NI: Copy + Eq + Debug + 'static,
122 EI: Copy + Eq + Debug + 'static,
123 NM: Map<Node<N, EI>, Key = NI> + 'graph,
124 NM::$iter<'graph>: ExactSizeIterator,
125 {
126 #[inline]
127 fn len(&self) -> usize {
128 self.inner.len()
129 }
130 }
131
132 impl<'graph, N, NI, EI, NM> FusedIterator for $name<'graph, N, NI, EI, NM>
133 where
134 N: 'graph,
135 NI: Copy + Eq + Debug + 'static,
136 EI: Copy + Eq + Debug + 'static,
137 NM: Map<Node<N, EI>, Key = NI> + 'graph,
138 NM::$iter<'graph>: FusedIterator,
139 {
140 }
141
142 impl<'graph, N, NI, EI, NM> DoubleEndedIterator for $name<'graph, N, NI, EI, NM>
143 where
144 N: 'graph,
145 NI: Copy + Eq + Debug + 'static,
146 EI: Copy + Eq + Debug + 'static,
147 NM: Map<Node<N, EI>, Key = NI> + 'graph,
148 NM::$iter<'graph>: DoubleEndedIterator,
149 {
150 fn next_back(&mut self) -> Option<Self::Item> {
151 self.inner
152 .next_back()
153 .map(|(index, node)| (index, node.$weight()))
154 }
155 }
156 };
157}
158
159impl_node_weights!(NodeWeights, "An immutable", Iter, &'graph N, weight);
160impl_node_weights!(
161 NodeWeightsMut,
162 "A mutable",
163 IterMut,
164 &'graph mut N,
165 weight_mut
166);
167
168macro_rules! impl_edge_weights {
169 ($name:ident, $word:literal, $iter:ident, $item:ty, $weight:ident) => {
170 #[doc = concat!($word, " iterator over the [`Graph`]'s edges' weights.")]
171 #[derive(Debug)]
172 pub struct $name<'graph, E, NI, EI, EM>
173 where
174 E: 'graph,
175 NI: Copy + Eq + Debug + 'static,
176 EI: Copy + Eq + Debug + 'static,
177 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + 'graph,
178 {
179 pub(super) inner: EM::$iter<'graph>,
180 }
181
182 impl<'graph, E, NI, EI, EM> Iterator for $name<'graph, E, NI, EI, EM>
183 where
184 E: 'graph,
185 NI: Copy + Eq + Debug + 'static,
186 EI: Copy + Eq + Debug + 'static,
187 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + 'graph,
188 {
189 type Item = (EM::Key, $item);
190
191 #[inline]
192 fn next(&mut self) -> Option<Self::Item> {
193 self.inner
194 .next()
195 .map(|(index, edge)| (index, edge.$weight()))
196 }
197
198 #[inline]
199 fn size_hint(&self) -> (usize, Option<usize>) {
200 self.inner.size_hint()
201 }
202 }
203
204 impl<'graph, E, NI, EI, EM> ExactSizeIterator for $name<'graph, E, NI, EI, EM>
205 where
206 E: 'graph,
207 NI: Copy + Eq + Debug + 'static,
208 EI: Copy + Eq + Debug + 'static,
209 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + 'graph,
210 EM::$iter<'graph>: ExactSizeIterator,
211 {
212 #[inline]
213 fn len(&self) -> usize {
214 self.inner.len()
215 }
216 }
217
218 impl<'graph, E, NI, EI, EM> FusedIterator for $name<'graph, E, NI, EI, EM>
219 where
220 E: 'graph,
221 NI: Copy + Eq + Debug + 'static,
222 EI: Copy + Eq + Debug + 'static,
223 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + 'graph,
224 EM::$iter<'graph>: FusedIterator,
225 {
226 }
227 };
228}
229
230impl_edge_weights!(EdgeWeights, "An immutable", Iter, &'graph E, weight);
231impl_edge_weights!(
232 EdgeWeightsMut,
233 "A mutable",
234 IterMut,
235 &'graph mut E,
236 weight_mut
237);
238
239macro_rules! impl_edges_iter {
240 ($name:ident, $word:literal, $next:ident) => {
241 #[doc = concat!("Iterator over ", $word, "s of a graph's node.\n")]
242 #[derive(Debug)]
245 pub struct $name<'graph, E, NI, EI, EM>
246 where
247 NI: Copy + Eq + Debug + 'static,
248 EI: Copy + Eq + Debug + 'static,
249 EM: Map<Edge<E, NI, EI>, Key = EI>,
250 {
251 edges: &'graph EM,
252 next: Option<EI>,
253 _phantom: PhantomData<(E, NI, EI)>,
254 }
255
256 impl<'graph, E, NI, EI, EM> $name<'graph, E, NI, EI, EM>
257 where
258 E: 'graph,
259 NI: Copy + Eq + Debug + 'static,
260 EI: Copy + Eq + Debug + 'static,
261 EM: Map<Edge<E, NI, EI>, Key = EI> + 'graph,
262 {
263 pub(super) fn new(edges: &'graph EM, next: Option<EI>) -> Self {
264 $name {
265 edges,
266 next,
267 _phantom: Default::default(),
268 }
269 }
270 }
271
272 impl<'graph, E, NI, EI, EM> Iterator for $name<'graph, E, NI, EI, EM>
273 where
274 E: 'graph,
275 NI: Copy + Eq + Debug + 'static,
276 EI: Copy + Eq + Debug + 'static,
277 EM: Map<Edge<E, NI, EI>, Key = EI> + 'graph,
278 {
279 type Item = (EI, &'graph Edge<E, NI, EI>);
280
281 #[inline]
282 fn next(&mut self) -> Option<Self::Item> {
283 let next = self.next;
284 if let Some(idx) = next {
285 let edge = self.edges.get(idx).unwrap();
286 self.next = edge.$next;
287 Some((idx, edge))
288 } else {
289 None
290 }
291 }
292 }
293 };
294}
295
296impl_edges_iter!(Inputs, "input", next_incoming_edge);
297impl_edges_iter!(Outputs, "output", next_outgoing_edge);
298
299macro_rules! impl_neighbours_iter {
300 ($name:ident, $word:literal, $next:ident, $node:ident) => {
301 #[doc = concat!(
302 "Iterator over ", $word, "s of a graph node.\n\n",
303 "Emits tuples containing ", $word, "s' node indices and immutable references to ",
304 "their weights."
305 )]
306 #[derive(Debug)]
307 pub struct $name<'graph, N, E, NI, EI, NM, EM>
308 where
309 NI: Copy + Eq + Debug + 'static,
310 EI: Copy + Eq + Debug + 'static,
311 NM: Map<Node<N, EI>, Key = NI>,
312 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
313 {
314 pub(super) graph: &'graph FrozenGraph<N, E, NI, EI, NM, EM>,
315 pub(super) next: Option<EI>,
316 }
317
318 impl<'graph, N, E, NI, EI, NM, EM> Iterator for $name<'graph, N, E, NI, EI, NM, EM>
319 where
320 N: 'graph,
321 E: 'graph,
322 NI: Copy + Eq + Debug + 'static,
323 EI: Copy + Eq + Debug + 'static,
324 NM: Map<Node<N, EI>, Key = NI> + 'graph,
325 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + 'graph,
326 {
327 type Item = (NI, &'graph N);
328
329 #[inline]
330 fn next(&mut self) -> Option<Self::Item> {
331 let next = self.next;
332 next.map(|index| {
333 let edge = self.graph.edges.get(index).unwrap();
334 self.next = edge.$next;
335
336 let node_index = edge.$node;
337 let node = self.graph.nodes.get(node_index).unwrap();
338 (node_index, &node.weight)
339 })
340 }
341 }
342 };
343}
344
345impl_neighbours_iter!(Successors, "successor", next_outgoing_edge, to);
346impl_neighbours_iter!(Predecessors, "predecessor", next_incoming_edge, from);
347
348pub trait Walker<N, E, NI, EI, NM, EM>
355where
356 NI: Copy + Eq + Debug + 'static,
357 EI: Copy + Eq + Debug + 'static,
358 NM: Map<Node<N, EI>, Key = NI>,
359 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
360{
361 type Item<'a>
363 where
364 N: 'a,
365 E: 'a,
366 EM: 'a,
367 NM: 'a;
368
369 fn walk_next<'a>(
371 &mut self,
372 graph: &'a FrozenGraph<N, E, NI, EI, NM, EM>,
373 ) -> Option<Self::Item<'a>>;
374}
375
376pub trait WalkerMut<N, E, NI, EI, NM, EM>
383where
384 NI: Copy + Eq + Debug + 'static,
385 EI: Copy + Eq + Debug + 'static,
386 NM: Map<Node<N, EI>, Key = NI>,
387 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
388 Self: Walker<N, E, NI, EI, NM, EM>,
389{
390 fn walk_next_mut<'a>(
392 &mut self,
393 graph: &'a mut FrozenGraph<N, E, NI, EI, NM, EM>,
394 ) -> Option<Self::Item<'a>>;
395}
396
397pub trait EdgesWalker<E, NI, EI, EM>
404where
405 NI: Copy + Eq + Debug + 'static,
406 EI: Copy + Eq + Debug + 'static,
407 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
408{
409 type Item<'a>
411 where
412 E: 'a,
413 EM: 'a;
414
415 fn walk_edges_next<'a>(&mut self, edges: &'a Edges<E, NI, EI, EM>) -> Option<Self::Item<'a>>;
417}
418
419pub trait EdgesWalkerMut<E, NI, EI, EM>
426where
427 NI: Copy + Eq + Debug + 'static,
428 EI: Copy + Eq + Debug + 'static,
429 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
430 Self: EdgesWalker<E, NI, EI, EM>,
431{
432 fn walk_edges_next_mut<'a>(
434 &mut self,
435 edges: &'a mut Edges<E, NI, EI, EM>,
436 ) -> Option<Self::Item<'a>>;
437}
438
439macro_rules! impl_walk_neighbours {
440 ($name:ident, $word:literal, $next:ident, $node:ident) => {
441 #[doc = concat!("A \"walker\" over the ", $word, "s of a node.")]
442 #[derive(Clone, Debug)]
443 pub struct $name<EI: Copy + Eq + Debug + 'static> {
444 pub(super) next: Option<EI>,
445 }
446
447 impl<N, E, NI, EI, NM, EM> Walker<N, E, NI, EI, NM, EM> for $name<EI>
448 where
449 NI: Copy + Eq + Debug + 'static,
450 EI: Copy + Eq + Debug + 'static,
451 NM: Map<Node<N, EI>, Key = NI>,
452 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
453 {
454 type Item<'a> = NI where N: 'a, E: 'a, EM: 'a, NM: 'a;
455
456 fn walk_next<'a>(
457 &mut self,
458 graph: &'a FrozenGraph<N, E, NI, EI, NM, EM>,
459 ) -> Option<Self::Item<'a>> {
460 let cur_index = self.next?;
461 let edge = graph.edges.get(cur_index).unwrap();
462 self.next = edge.$next;
463 Some(edge.$node)
464 }
465 }
466
467 impl<E, NI, EI, EM> EdgesWalker<E, NI, EI, EM> for $name<EI>
468 where
469 NI: Copy + Eq + Debug + 'static,
470 EI: Copy + Eq + Debug + 'static,
471 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
472 {
473 type Item<'a> = NI where E: 'a, EM: 'a;
474
475 fn walk_edges_next<'a>(
476 &mut self,
477 edges: &'a Edges<E, NI, EI, EM>,
478 ) -> Option<Self::Item<'a>> {
479 let cur_index = self.next?;
480 let edge = edges.get(cur_index).unwrap();
481 self.next = edge.$next;
482 Some(edge.$node)
483 }
484 }
485 };
486}
487
488impl_walk_neighbours!(WalkSuccessors, "successor", next_outgoing_edge, to);
489impl_walk_neighbours!(WalkPredecessors, "predecessor", next_incoming_edge, from);
490
491macro_rules! impl_walk_edges {
492 ($name:ident, $word:literal, $next:ident) => {
493 #[doc = concat!("A \"walker\" over the ", $word, " edges of a node.")]
494 #[derive(Clone, Debug)]
495 pub struct $name<EI: Copy + Eq + Debug + 'static> {
496 pub(super) next: Option<EI>,
497 }
498
499 impl<N, E, NI, EI, NM, EM> Walker<N, E, NI, EI, NM, EM> for $name<EI>
500 where
501 NI: Copy + Eq + Debug + 'static,
502 EI: Copy + Eq + Debug + 'static,
503 NM: Map<Node<N, EI>, Key = NI>,
504 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
505 {
506 type Item<'a> = (EI, &'a Edge<E, NI, EI>) where N: 'a, E: 'a, EM: 'a, NM: 'a;
507
508 fn walk_next<'a>(
509 &mut self,
510 graph: &'a FrozenGraph<N, E, NI, EI, NM, EM>,
511 ) -> Option<Self::Item<'a>> {
512 let cur_index = self.next?;
513 let edge = &graph.edges[cur_index];
514 self.next = edge.$next;
515 Some((cur_index, edge))
516 }
517 }
518
519 impl<E, NI, EI, EM> EdgesWalker<E, NI, EI, EM> for $name<EI>
520 where
521 NI: Copy + Eq + Debug + 'static,
522 EI: Copy + Eq + Debug + 'static,
523 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
524 {
525 type Item<'a> = (EI, &'a Edge<E, NI, EI>) where E: 'a, EM: 'a;
526
527 fn walk_edges_next<'a>(
528 &mut self,
529 edges: &'a Edges<E, NI, EI, EM>,
530 ) -> Option<Self::Item<'a>> {
531 let cur_index = self.next?;
532 let edge = &edges[cur_index];
533 self.next = edge.$next;
534 Some((cur_index, edge))
535 }
536 }
537
538 impl<E, NI, EI, EM> EdgesWalkerMut<E, NI, EI, EM> for $name<EI>
539 where
540 NI: Copy + Eq + Debug + 'static,
541 EI: Copy + Eq + Debug + 'static,
542 EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
543 {
544 fn walk_edges_next_mut<'a>(
545 &mut self,
546 edges: &'a mut Edges<E, NI, EI, EM>,
547 ) -> Option<Self::Item<'a>> {
548 let cur_index = self.next?;
549 let edge = &mut edges[cur_index];
550 self.next = edge.$next;
551 Some((cur_index, edge))
552 }
553 }
554 };
555}
556
557impl_walk_edges!(WalkOutputs, "outgoing", next_outgoing_edge);
558impl_walk_edges!(WalkInputs, "incoming", next_incoming_edge);