1
2use prelude::*;
3
4use fixedbitset::FixedBitSet;
5use std::collections::HashSet;
6use std::marker::PhantomData;
7
8use visit::{
9 GraphBase,
10 GraphProp,
11 IntoEdgeReferences,
12 IntoEdges,
13 IntoNeighbors,
14 IntoNeighborsDirected,
15 IntoNodeIdentifiers,
16 IntoNodeReferences,
17 NodeIndexable,
18 NodeRef,
19 VisitMap,
20 Visitable,
21};
22use visit::{Data, NodeCompactIndexable, NodeCount};
23use data::{DataMap};
24
25pub trait FilterNode<N>
27{
28 fn include_node(&self, node: N) -> bool;
30}
31
32impl<F, N> FilterNode<N> for F
33 where F: Fn(N) -> bool,
34{
35 fn include_node(&self, n: N) -> bool {
36 (*self)(n)
37 }
38}
39
40impl<N> FilterNode<N> for FixedBitSet
42 where FixedBitSet: VisitMap<N>,
43{
44 fn include_node(&self, n: N) -> bool {
45 self.is_visited(&n)
46 }
47}
48
49impl<N, S> FilterNode<N> for HashSet<N, S>
51 where HashSet<N, S>: VisitMap<N>,
52{
53 fn include_node(&self, n: N) -> bool {
54 self.is_visited(&n)
55 }
56}
57
58#[derive(Copy, Clone, Debug)]
60pub struct NodeFiltered<G, F>(pub G, pub F);
61
62impl<F, G> NodeFiltered<G, F>
63 where G: GraphBase,
64 F: Fn(G::NodeId) -> bool,
65{
66 pub fn from_fn(graph: G, filter: F) -> Self {
68 NodeFiltered(graph, filter)
69 }
70}
71
72impl<G, F> GraphBase for NodeFiltered<G, F> where G: GraphBase {
73 type NodeId = G::NodeId;
74 type EdgeId = G::EdgeId;
75}
76
77impl<'a, G, F> IntoNeighbors for &'a NodeFiltered<G, F>
78 where G: IntoNeighbors,
79 F: FilterNode<G::NodeId>,
80{
81 type Neighbors = NodeFilteredNeighbors<'a, G::Neighbors, F>;
82 fn neighbors(self, n: G::NodeId) -> Self::Neighbors {
83 NodeFilteredNeighbors {
84 include_source: self.1.include_node(n),
85 iter: self.0.neighbors(n),
86 f: &self.1,
87 }
88 }
89}
90
91pub struct NodeFilteredNeighbors<'a, I, F: 'a>
93{
94 include_source: bool,
95 iter: I,
96 f: &'a F,
97}
98
99impl<'a, I, F> Iterator for NodeFilteredNeighbors<'a, I, F>
100 where I: Iterator,
101 I::Item: Copy,
102 F: FilterNode<I::Item>,
103{
104 type Item = I::Item;
105 fn next(&mut self) -> Option<Self::Item> {
106 let f = self.f;
107 if !self.include_source {
108 None
109 } else {
110 self.iter.find(move |&target| f.include_node(target))
111 }
112 }
113}
114
115impl<'a, G, F> IntoNeighborsDirected for &'a NodeFiltered<G, F>
116 where G: IntoNeighborsDirected,
117 F: FilterNode<G::NodeId>,
118{
119 type NeighborsDirected = NodeFilteredNeighbors<'a, G::NeighborsDirected, F>;
120 fn neighbors_directed(self, n: G::NodeId, dir: Direction)
121 -> Self::NeighborsDirected {
122 NodeFilteredNeighbors {
123 include_source: self.1.include_node(n),
124 iter: self.0.neighbors_directed(n, dir),
125 f: &self.1,
126 }
127 }
128}
129
130impl<'a, G, F> IntoNodeIdentifiers for &'a NodeFiltered<G, F>
131 where G: IntoNodeIdentifiers,
132 F: FilterNode<G::NodeId>,
133{
134 type NodeIdentifiers = NodeFilteredNeighbors<'a, G::NodeIdentifiers, F>;
135 fn node_identifiers(self) -> Self::NodeIdentifiers {
136 NodeFilteredNeighbors {
137 include_source: true,
138 iter: self.0.node_identifiers(),
139 f: &self.1,
140 }
141 }
142}
143
144impl<'a, G, F> IntoNodeReferences for &'a NodeFiltered<G, F>
145 where G: IntoNodeReferences,
146 F: FilterNode<G::NodeId>,
147{
148 type NodeRef = G::NodeRef;
149 type NodeReferences = NodeFilteredNodes<'a, G::NodeReferences, F>;
150 fn node_references(self) -> Self::NodeReferences {
151 NodeFilteredNodes {
152 include_source: true,
153 iter: self.0.node_references(),
154 f: &self.1,
155 }
156 }
157}
158
159pub struct NodeFilteredNodes<'a, I, F: 'a>
161{
162 include_source: bool,
163 iter: I,
164 f: &'a F,
165}
166
167impl<'a, I, F> Iterator for NodeFilteredNodes<'a, I, F>
168 where I: Iterator,
169 I::Item: Copy + NodeRef,
170 F: FilterNode<<I::Item as NodeRef>::NodeId>,
171{
172 type Item = I::Item;
173 fn next(&mut self) -> Option<Self::Item> {
174 let f = self.f;
175 if !self.include_source {
176 None
177 } else {
178 self.iter.find(move |&target| f.include_node(target.id()))
179 }
180 }
181}
182
183impl<'a, G, F> IntoEdgeReferences for &'a NodeFiltered<G, F>
184 where G: IntoEdgeReferences,
185 F: FilterNode<G::NodeId>,
186{
187 type EdgeRef = G::EdgeRef;
188 type EdgeReferences = NodeFilteredEdgeReferences<'a, G, G::EdgeReferences, F>;
189 fn edge_references(self) -> Self::EdgeReferences {
190 NodeFilteredEdgeReferences {
191 graph: PhantomData,
192 iter: self.0.edge_references(),
193 f: &self.1,
194 }
195 }
196}
197
198pub struct NodeFilteredEdgeReferences<'a, G, I, F: 'a>
200{
201 graph: PhantomData<G>,
202 iter: I,
203 f: &'a F,
204}
205
206impl<'a, G, I, F> Iterator for NodeFilteredEdgeReferences<'a, G, I, F>
207 where F: FilterNode<G::NodeId>,
208 G: IntoEdgeReferences,
209 I: Iterator<Item=G::EdgeRef>,
210{
211 type Item = I::Item;
212 fn next(&mut self) -> Option<Self::Item> {
213 let f = self.f;
214 self.iter.find(move |&edge| f.include_node(edge.source()) &&
215 f.include_node(edge.target()))
216 }
217}
218
219impl<'a, G, F> IntoEdges for &'a NodeFiltered<G, F>
220 where G: IntoEdges,
221 F: FilterNode<G::NodeId>,
222{
223 type Edges = NodeFilteredEdges<'a, G, G::Edges, F>;
224 fn edges(self, a: G::NodeId) -> Self::Edges {
225 NodeFilteredEdges {
226 graph: PhantomData,
227 include_source: self.1.include_node(a),
228 iter: self.0.edges(a),
229 f: &self.1,
230 }
231 }
232}
233
234
235pub struct NodeFilteredEdges<'a, G, I, F: 'a>
237{
238 graph: PhantomData<G>,
239 include_source: bool,
240 iter: I,
241 f: &'a F,
242}
243
244
245impl<'a, G, I, F> Iterator for NodeFilteredEdges<'a, G, I, F>
246 where F: FilterNode<G::NodeId>,
247 G: IntoEdges,
248 I: Iterator<Item=G::EdgeRef>,
249{
250 type Item = I::Item;
251 fn next(&mut self) -> Option<Self::Item> {
252 if !self.include_source {
253 None
254 } else {
255 let f = self.f;
256 self.iter.find(move |&edge| f.include_node(edge.target()))
257 }
258 }
259}
260
261impl<G, F> DataMap for NodeFiltered<G, F>
262 where G: DataMap,
263 F: FilterNode<G::NodeId>,
264{
265 fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
266 if self.1.include_node(id) {
267 self.0.node_weight(id)
268 } else {
269 None
270 }
271 }
272
273 fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
274 self.0.edge_weight(id)
275 }
276}
277
278macro_rules! access0 {
279 ($e:expr) => ($e.0)
280}
281
282Data!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
283NodeIndexable!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
284GraphProp!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
285Visitable!{delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]}
286
287pub trait FilterEdge<Edge> {
289 fn include_edge(&self, edge: Edge) -> bool;
291}
292
293impl<F, N> FilterEdge<N> for F
294 where F: Fn(N) -> bool,
295{
296 fn include_edge(&self, n: N) -> bool {
297 (*self)(n)
298 }
299}
300
301#[derive(Copy, Clone, Debug)]
310pub struct EdgeFiltered<G, F>(pub G, pub F);
311
312impl<F, G> EdgeFiltered<G, F>
313 where G: IntoEdgeReferences,
314 F: Fn(G::EdgeRef) -> bool,
315{
316 pub fn from_fn(graph: G, filter: F) -> Self {
318 EdgeFiltered(graph, filter)
319 }
320}
321
322impl<G, F> GraphBase for EdgeFiltered<G, F> where G: GraphBase {
323 type NodeId = G::NodeId;
324 type EdgeId = G::EdgeId;
325}
326
327impl<'a, G, F> IntoNeighbors for &'a EdgeFiltered<G, F>
328 where G: IntoEdges,
329 F: FilterEdge<G::EdgeRef>,
330{
331 type Neighbors = EdgeFilteredNeighbors<'a, G, F>;
332 fn neighbors(self, n: G::NodeId) -> Self::Neighbors {
333 EdgeFilteredNeighbors {
334 iter: self.0.edges(n),
335 f: &self.1,
336 }
337 }
338}
339
340pub struct EdgeFilteredNeighbors<'a, G, F: 'a>
342 where G: IntoEdges,
343{
344 iter: G::Edges,
345 f: &'a F,
346}
347
348impl<'a, G, F> Iterator for EdgeFilteredNeighbors<'a, G, F>
349 where F: FilterEdge<G::EdgeRef>,
350 G: IntoEdges,
351{
352 type Item = G::NodeId;
353 fn next(&mut self) -> Option<Self::Item> {
354 let f = self.f;
355 (&mut self.iter).filter_map(move |edge| {
356 if f.include_edge(edge) {
357 Some(edge.target())
358 } else { None }
359 }).next()
360 }
361}
362
363impl<'a, G, F> IntoEdgeReferences for &'a EdgeFiltered<G, F>
364 where G: IntoEdgeReferences,
365 F: FilterEdge<G::EdgeRef>,
366{
367 type EdgeRef = G::EdgeRef;
368 type EdgeReferences = EdgeFilteredEdges<'a, G, G::EdgeReferences, F>;
369 fn edge_references(self) -> Self::EdgeReferences {
370 EdgeFilteredEdges {
371 graph: PhantomData,
372 iter: self.0.edge_references(),
373 f: &self.1,
374 }
375 }
376}
377
378impl<'a, G, F> IntoEdges for &'a EdgeFiltered<G, F>
379 where G: IntoEdges,
380 F: FilterEdge<G::EdgeRef>,
381{
382 type Edges = EdgeFilteredEdges<'a, G, G::Edges, F>;
383 fn edges(self, n: G::NodeId) -> Self::Edges {
384 EdgeFilteredEdges {
385 graph: PhantomData,
386 iter: self.0.edges(n),
387 f: &self.1,
388 }
389 }
390}
391
392pub struct EdgeFilteredEdges<'a, G, I, F: 'a>
394{
395 graph: PhantomData<G>,
396 iter: I,
397 f: &'a F,
398}
399
400impl<'a, G, I, F> Iterator for EdgeFilteredEdges<'a, G, I, F>
401 where F: FilterEdge<G::EdgeRef>,
402 G: IntoEdgeReferences,
403 I: Iterator<Item=G::EdgeRef>,
404{
405 type Item = I::Item;
406 fn next(&mut self) -> Option<Self::Item> {
407 let f = self.f;
408 self.iter.find(move |&edge| f.include_edge(edge))
409 }
410}
411
412Data!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
413GraphProp!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
414IntoNodeIdentifiers!{delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
415IntoNodeReferences!{delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
416NodeCompactIndexable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
417NodeCount!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
418NodeIndexable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
419Visitable!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}