spade/delaunay_core/handles/iterators/
circular_iterator.rs

1use core::marker::PhantomData;
2
3use super::super::DirectedEdgeHandle;
4
5pub trait NextBackFn {
6    fn next<V, DE, UE, F>(
7        edge_handle: DirectedEdgeHandle<V, DE, UE, F>,
8    ) -> DirectedEdgeHandle<V, DE, UE, F>;
9
10    fn next_back<V, DE, UE, F>(
11        edge_handle: DirectedEdgeHandle<V, DE, UE, F>,
12    ) -> DirectedEdgeHandle<V, DE, UE, F>;
13}
14
15pub struct CircularIterator<'a, V, DE, UE, F, NB> {
16    pub(super) current_handle: DirectedEdgeHandle<'a, V, DE, UE, F>,
17    final_handle: DirectedEdgeHandle<'a, V, DE, UE, F>,
18    iteration_finished: bool,
19    next_back_fn: PhantomData<NB>,
20}
21
22impl<'a, V, DE, UE, F, NB: NextBackFn> CircularIterator<'a, V, DE, UE, F, NB> {
23    pub fn new(start_edge: DirectedEdgeHandle<'a, V, DE, UE, F>) -> Self {
24        CircularIterator {
25            current_handle: start_edge,
26            final_handle: start_edge,
27            iteration_finished: false,
28            next_back_fn: Default::default(),
29        }
30    }
31
32    pub fn new_empty(some_edge: DirectedEdgeHandle<'a, V, DE, UE, F>) -> Self {
33        CircularIterator {
34            current_handle: some_edge,
35            final_handle: some_edge,
36            iteration_finished: true,
37            next_back_fn: Default::default(),
38        }
39    }
40}
41
42impl<'a, V, DE, UE, F, NB: NextBackFn> Iterator for CircularIterator<'a, V, DE, UE, F, NB> {
43    type Item = DirectedEdgeHandle<'a, V, DE, UE, F>;
44
45    fn next(&mut self) -> Option<DirectedEdgeHandle<'a, V, DE, UE, F>> {
46        if self.iteration_finished {
47            return None;
48        }
49        let result = self.current_handle;
50        self.current_handle = NB::next(self.current_handle);
51        if self.current_handle == self.final_handle {
52            self.iteration_finished = true;
53        }
54        Some(result)
55    }
56}
57
58impl<'a, V, DE, UE, F, NB: NextBackFn> DoubleEndedIterator
59    for CircularIterator<'a, V, DE, UE, F, NB>
60{
61    fn next_back(&mut self) -> Option<DirectedEdgeHandle<'a, V, DE, UE, F>> {
62        if self.iteration_finished {
63            return None;
64        }
65        self.final_handle = NB::next_back(self.final_handle);
66        if self.current_handle == self.final_handle {
67            self.iteration_finished = true;
68        }
69        Some(self.final_handle)
70    }
71}