1use std::marker::PhantomData;
6use std::ops::AddAssign;
7
8use num_traits::{one, zero, One, Zero};
9
10use super::control::*;
11use prelude::*;
12use props::*;
13
14pub trait Visitor<G: WithEdge> {
16 fn start(&mut self, _g: &G) -> Control {
17 Control::Continue
18 }
19
20 fn finish(&mut self, _g: &G) -> Control {
21 Control::Continue
22 }
23
24 fn discover_root_vertex(&mut self, _g: &G, _v: Vertex<G>) -> Control {
25 Control::Continue
26 }
27
28 fn finish_root_vertex(&mut self, _g: &G, _v: Vertex<G>) -> Control {
29 Control::Continue
30 }
31
32 fn discover_vertex(&mut self, _g: &G, _v: Vertex<G>) -> Control {
33 Control::Continue
34 }
35
36 fn finish_vertex(&mut self, _g: &G, _v: Vertex<G>) -> Control {
37 Control::Continue
38 }
39
40 fn discover_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
41 Control::Continue
42 }
43
44 fn finish_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
45 Control::Continue
46 }
47
48 fn discover_tree_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
49 Control::Continue
50 }
51
52 fn finish_tree_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
53 Control::Continue
54 }
55
56 fn discover_back_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
57 Control::Continue
58 }
59
60 fn discover_cross_or_forward_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
61 Control::Continue
62 }
63}
64
65impl<'a, G, V> Visitor<G> for &'a mut V
66where
67 G: WithEdge,
68 V: Visitor<G>,
69{
70 fn start(&mut self, g: &G) -> Control {
71 V::start(self, g)
72 }
73
74 fn finish(&mut self, g: &G) -> Control {
75 V::start(self, g)
76 }
77
78 fn discover_root_vertex(&mut self, g: &G, v: Vertex<G>) -> Control {
79 V::discover_root_vertex(self, g, v)
80 }
81
82 fn finish_root_vertex(&mut self, g: &G, v: Vertex<G>) -> Control {
83 V::finish_root_vertex(self, g, v)
84 }
85
86 fn discover_vertex(&mut self, g: &G, v: Vertex<G>) -> Control {
87 V::discover_vertex(self, g, v)
88 }
89
90 fn finish_vertex(&mut self, g: &G, v: Vertex<G>) -> Control {
91 V::finish_vertex(self, g, v)
92 }
93
94 fn discover_edge(&mut self, g: &G, e: Edge<G>) -> Control {
95 V::discover_edge(self, g, e)
96 }
97
98 fn finish_edge(&mut self, g: &G, e: Edge<G>) -> Control {
99 V::finish_edge(self, g, e)
100 }
101
102 fn discover_tree_edge(&mut self, g: &G, e: Edge<G>) -> Control {
103 V::discover_tree_edge(self, g, e)
104 }
105
106 fn finish_tree_edge(&mut self, g: &G, e: Edge<G>) -> Control {
107 V::finish_tree_edge(self, g, e)
108 }
109
110 fn discover_back_edge(&mut self, g: &G, e: Edge<G>) -> Control {
111 V::discover_back_edge(self, g, e)
112 }
113
114 fn discover_cross_or_forward_edge(&mut self, g: &G, e: Edge<G>) -> Control {
115 V::discover_cross_or_forward_edge(self, g, e)
116 }
117}
118
119#[derive(Clone, Copy, Debug, PartialEq, Eq)]
120pub struct EmptyVisitor;
121
122impl<G: WithEdge> Visitor<G> for EmptyVisitor {}
123
124macro_rules! def_visitor_tuple_m {
125 ($m:ident ; $($name:ident),*) => (
126 #[allow(non_snake_case)]
127 #[cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
128 fn $m(&mut self, g: &G) -> Control {
129 let ($(ref mut $name),*) = *self;
130 let r = Control::Continue;
131 $(
132 let r = if r == Control::Continue {
133 $name.$m(g)
134 } else {
135 return Control::Break;
136 };
137 )*
138 r
139 }
140 );
141 ($t:ident, $m:ident, $($name:ident),*) => (
142 #[allow(non_snake_case)]
143 #[cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
144 fn $m(&mut self, g: &G, item: $t<G>) -> Control {
145 let ($(ref mut $name),*) = *self;
146 let r = Control::Continue;
147 $(
148 let r = if r == Control::Continue {
149 $name.$m(g, item)
150 } else {
151 return Control::Break;
152 };
153 )*
154 r
155 }
156 )
157}
158
159macro_rules! def_visitor_tuple {
160 ($($name:ident),*) => (
161 impl<G, $($name),*> Visitor<G> for ($($name),*)
162 where G: WithEdge,
163 $($name: Visitor<G>),*
164 {
165 def_visitor_tuple_m!{start ; $($name),*}
166 def_visitor_tuple_m!{finish ; $($name),*}
167
168 def_visitor_tuple_m!{Vertex, discover_root_vertex, $($name),*}
169 def_visitor_tuple_m!{Vertex, finish_root_vertex, $($name),*}
170
171 def_visitor_tuple_m!{Vertex, discover_vertex, $($name),*}
172 def_visitor_tuple_m!{Vertex, finish_vertex, $($name),*}
173
174 def_visitor_tuple_m!{Edge, discover_edge, $($name),*}
175 def_visitor_tuple_m!{Edge, finish_edge, $($name),*}
176
177 def_visitor_tuple_m!{Edge, discover_tree_edge, $($name),*}
178 def_visitor_tuple_m!{Edge, finish_tree_edge, $($name),*}
179
180 def_visitor_tuple_m!{Edge, discover_back_edge, $($name),*}
181 def_visitor_tuple_m!{Edge, discover_cross_or_forward_edge, $($name),*}
182 }
183 )
184}
185
186def_visitor_tuple!(A, B);
187def_visitor_tuple!(A, B, C);
188def_visitor_tuple!(A, B, C, D);
189
190#[derive(Clone, Copy, PartialEq, Eq, Debug)]
191pub enum TraverseEvent<G: WithEdge> {
192 Start,
193 Finish,
194 DiscoverRootVertex(Vertex<G>),
195 FinishRootVertex(Vertex<G>),
196 DiscoverVertex(Vertex<G>),
197 FinishVertex(Vertex<G>),
198 DiscoverEdge(Edge<G>),
199 FinishEdge(Edge<G>),
200 DiscoverTreeEdge(Edge<G>),
201 FinishTreeEdge(Edge<G>),
202 DiscoverBackEdge(Edge<G>),
203 DiscoverCrossOrForwardEdge(Edge<G>),
204}
205
206pub struct OnTraverseEvent<F>(pub F);
207
208impl<G, F, R> Visitor<G> for OnTraverseEvent<F>
209where
210 G: WithEdge,
211 F: FnMut(TraverseEvent<G>) -> R,
212 R: Into<Control>,
213{
214 fn start(&mut self, _g: &G) -> Control {
215 (self.0)(TraverseEvent::Start).into()
216 }
217
218 fn finish(&mut self, _g: &G) -> Control {
219 (self.0)(TraverseEvent::Finish).into()
220 }
221
222 fn discover_root_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
223 (self.0)(TraverseEvent::DiscoverRootVertex(v)).into()
224 }
225
226 fn finish_root_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
227 (self.0)(TraverseEvent::FinishRootVertex(v)).into()
228 }
229
230 fn discover_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
231 (self.0)(TraverseEvent::DiscoverVertex(v)).into()
232 }
233
234 fn finish_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
235 (self.0)(TraverseEvent::FinishVertex(v)).into()
236 }
237
238 fn discover_edge(&mut self, _g: &G, e: Edge<G>) -> Control {
239 (self.0)(TraverseEvent::DiscoverEdge(e)).into()
240 }
241
242 fn finish_edge(&mut self, _g: &G, e: Edge<G>) -> Control {
243 (self.0)(TraverseEvent::FinishEdge(e)).into()
244 }
245
246 fn discover_tree_edge(&mut self, _g: &G, e: Edge<G>) -> Control {
247 (self.0)(TraverseEvent::DiscoverTreeEdge(e)).into()
248 }
249
250 fn finish_tree_edge(&mut self, _g: &G, e: Edge<G>) -> Control {
251 (self.0)(TraverseEvent::FinishTreeEdge(e)).into()
252 }
253
254 fn discover_back_edge(&mut self, _g: &G, e: Edge<G>) -> Control {
255 (self.0)(TraverseEvent::DiscoverBackEdge(e)).into()
256 }
257
258 fn discover_cross_or_forward_edge(&mut self, _g: &G, e: Edge<G>) -> Control {
259 (self.0)(TraverseEvent::DiscoverCrossOrForwardEdge(e)).into()
260 }
261}
262
263pub trait VisitVertex<G: WithEdge> {
266 fn visit_vertex(&mut self, g: &G, v: Vertex<G>) -> Control;
267}
268
269impl<G, F, R> VisitVertex<G> for F
270where
271 G: WithEdge,
272 F: FnMut(Vertex<G>) -> R,
273 R: Into<Control>,
274{
275 fn visit_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
276 self(v).into()
277 }
278}
279
280macro_rules! def_on_vertex_visitor {
281 ($name:ident, $event:ident) => {
282 pub struct $name<V>(pub V);
283
284 impl<G, V> Visitor<G> for $name<V>
285 where
286 G: WithEdge,
287 V: VisitVertex<G>,
288 {
289 fn $event(&mut self, g: &G, v: Vertex<G>) -> Control {
290 self.0.visit_vertex(g, v)
291 }
292 }
293 };
294}
295
296def_on_vertex_visitor!(OnDiscoverRootVertex, discover_root_vertex);
297def_on_vertex_visitor!(OnFinishRootVertex, finish_root_vertex);
298
299def_on_vertex_visitor!(OnDiscoverVertex, discover_vertex);
300def_on_vertex_visitor!(OnFinishVertex, finish_vertex);
301
302pub trait VisitEdge<G: WithEdge> {
305 fn visit_edge(&mut self, g: &G, e: Edge<G>) -> Control;
306}
307
308impl<G, F, R> VisitEdge<G> for F
309where
310 G: WithEdge,
311 F: FnMut(Edge<G>) -> R,
312 R: Into<Control>,
313{
314 fn visit_edge(&mut self, _g: &G, e: Edge<G>) -> Control {
315 self(e).into()
316 }
317}
318
319macro_rules! def_on_edge_visitor {
320 ($name:ident, $event:ident) => {
321 pub struct $name<V>(pub V);
322
323 impl<G, V> Visitor<G> for $name<V>
324 where
325 G: WithEdge,
326 V: VisitEdge<G>,
327 {
328 fn $event(&mut self, g: &G, e: Edge<G>) -> Control {
329 self.0.visit_edge(g, e)
330 }
331 }
332 };
333}
334
335def_on_edge_visitor!(OnDiscoverEdge, discover_edge);
336def_on_edge_visitor!(OnFinishEdge, finish_edge);
337
338def_on_edge_visitor!(OnDiscoverTreeEdge, discover_tree_edge);
339def_on_edge_visitor!(OnFinishTreeEdge, finish_tree_edge);
340
341def_on_edge_visitor!(OnDiscoverBackEdge, discover_back_edge);
342def_on_edge_visitor!(OnDiscoverCrossOrBackEdge, discover_cross_or_forward_edge);
343
344use std::cell::Cell;
347
348pub trait Counter {
349 fn add1(&mut self);
350}
351
352impl<T> Counter for T
353where
354 T: One + AddAssign,
355{
356 fn add1(&mut self) {
357 *self += one();
358 }
359}
360
361pub struct Add1<'a, T: 'a>(pub &'a mut T);
362
363impl<'a, G, T> VisitVertex<G> for Add1<'a, T>
364where
365 G: WithEdge,
366 T: Counter,
367{
368 fn visit_vertex(&mut self, _g: &G, _v: Vertex<G>) -> Control {
369 self.0.add1();
370 Control::Continue
371 }
372}
373
374impl<'a, G, T> VisitEdge<G> for Add1<'a, T>
375where
376 G: WithEdge,
377 T: Counter,
378{
379 fn visit_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
380 self.0.add1();
381 Control::Continue
382 }
383}
384
385#[derive(Default)]
386pub struct Time<T> {
387 cur: Cell<T>,
388}
389
390impl<T> Time<T>
391where
392 T: Copy + Counter,
393{
394 #[inline]
395 fn get_and_inc(&self) -> T {
396 let mut t = self.cur.get();
397 t.add1();
398 self.cur.replace(t)
399 }
400}
401
402pub struct StampTime<'a, T: 'a, P: 'a>(pub &'a Time<T>, pub &'a mut P);
403
404impl<'a, G, T, P> VisitVertex<G> for StampTime<'a, T, P>
405where
406 G: WithEdge,
407 T: Copy + Counter,
408 P: VertexPropMut<G, T>,
409{
410 fn visit_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
411 self.1[v] = self.0.get_and_inc();
412 Control::Continue
413 }
414}
415
416pub struct RecordDistance<'a, P: 'a, T> {
417 dist: &'a mut P,
418 _marker: PhantomData<T>,
419}
420
421#[allow(non_snake_case)]
422pub fn RecordDistance<P, T>(dist: &mut P) -> RecordDistance<P, T> {
423 RecordDistance {
424 dist: dist,
425 _marker: PhantomData,
426 }
427}
428
429impl<'a, G, P, T> Visitor<G> for RecordDistance<'a, P, T>
430where
431 G: WithEdge,
432 P: VertexPropMut<G, T>,
433 T: Counter + Copy + Zero,
434{
435 fn discover_root_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
436 self.dist[v] = zero();
437 Control::Continue
438 }
439
440 fn discover_tree_edge(&mut self, g: &G, e: Edge<G>) -> Control {
441 let (u, v) = g.ends(e);
442 self.dist[v] = self.dist[u];
443 self.dist[v].add1();
444 Control::Continue
445 }
446}
447
448pub struct RecordParent<'a, P: 'a>(pub &'a mut P);
449
450impl<'a, G, P> Visitor<G> for RecordParent<'a, P>
451where
452 G: WithEdge,
453 P: VertexPropMut<G, OptionVertex<G>>,
454{
455 fn discover_root_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
456 self.0[v] = G::vertex_none();
457 Control::Continue
458 }
459
460 fn discover_tree_edge(&mut self, g: &G, e: Edge<G>) -> Control {
461 let (u, v) = g.ends(e);
462 self.0[v] = u.into();
463 Control::Continue
464 }
465}
466
467pub struct RecordParentEdge<'a, P: 'a>(pub &'a mut P);
468
469impl<'a, G, P> Visitor<G> for RecordParentEdge<'a, P>
470where
471 G: WithEdge<Kind = Undirected>,
472 P: VertexPropMut<G, OptionEdge<G>>,
473{
474 fn discover_root_vertex(&mut self, _g: &G, v: Vertex<G>) -> Control {
475 self.0[v] = G::edge_none();
476 Control::Continue
477 }
478
479 fn discover_tree_edge(&mut self, g: &G, e: Edge<G>) -> Control {
480 self.0[g.target(e)] = g.reverse(e).into();
481 Control::Continue
482 }
483}
484
485pub struct FarthestVertex<'a, G: WithVertex> {
486 cur_dist: usize,
487 dist: &'a mut usize,
488 v: &'a mut OptionVertex<G>,
489}
490
491#[allow(non_snake_case)]
492pub fn FarthestVertex<'a, G>(
493 v: &'a mut OptionVertex<G>,
494 dist: &'a mut usize,
495) -> FarthestVertex<'a, G>
496where
497 G: WithVertex,
498{
499 FarthestVertex {
500 cur_dist: 0,
501 dist: dist,
502 v: v,
503 }
504}
505
506impl<'a, G> Visitor<G> for FarthestVertex<'a, G>
507where
508 G: 'a + WithEdge,
509{
510 fn start(&mut self, _: &G) -> Control {
511 *self.dist = 0;
512 Control::Continue
513 }
514
515 fn finish_tree_edge(&mut self, _: &G, _: Edge<G>) -> Control {
516 self.cur_dist -= 1;
517 Control::Continue
518 }
519
520 fn discover_tree_edge(&mut self, g: &G, e: Edge<G>) -> Control {
521 self.cur_dist += 1;
522 if self.cur_dist > *self.dist {
523 *self.dist = self.cur_dist;
524 *self.v = g.target(e).into();
525 }
526 Control::Continue
527 }
528}
529
530