1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// use claim::debug_assert_ok;

use crate::data::Cursor;
use crate::data::DirectedEdge;
use crate::data::Point;
use crate::TotalOrd;

pub struct Iter<'a, T: 'a> {
  pub(crate) iter: std::slice::Iter<'a, Point<T, 2>>,
}
impl<'a, T> Iterator for Iter<'a, T> {
  type Item = &'a Point<T, 2>;
  fn next(&mut self) -> Option<&'a Point<T, 2>> {
    self.iter.next()
  }
}

pub struct IterMut<'a, T: 'a> {
  pub(crate) points: std::slice::IterMut<'a, Point<T, 2>>,
}

impl<'a, T> Iterator for IterMut<'a, T> {
  type Item = &'a mut Point<T, 2>;
  fn next(&mut self) -> Option<&'a mut Point<T, 2>> {
    self.points.next()
  }
}

pub struct EdgeIter<'a, T: 'a> {
  pub(crate) iter: CursorIter<'a, T>,
}

impl<'a, T: TotalOrd + Clone> Iterator for EdgeIter<'a, T> {
  type Item = DirectedEdge<'a, T, 2>;
  fn next(&mut self) -> Option<Self::Item> {
    let cursor = self.iter.next()?;
    let this_point = cursor.point();
    let next_point = cursor.next().point();
    Some(DirectedEdge {
      src: this_point,
      dst: next_point,
    })
  }
}

pub struct CursorIter<'a, T: 'a> {
  pub(crate) cursor_head: Cursor<'a, T>,
  pub(crate) cursor_tail: Cursor<'a, T>, // inclusive
  pub(crate) exhausted: bool,
}

impl<'a, T> Clone for CursorIter<'a, T> {
  fn clone(&self) -> Self {
    CursorIter {
      cursor_head: self.cursor_head,
      cursor_tail: self.cursor_tail,
      exhausted: self.exhausted,
    }
  }
}

impl<'a, 'b, T: TotalOrd> PartialEq<CursorIter<'b, T>> for CursorIter<'a, T> {
  fn eq(&self, other: &CursorIter<'b, T>) -> bool {
    if self.len() != other.len() {
      return false;
    }
    for (a, b) in self.clone().zip(other.clone()) {
      if a.point() != b.point() {
        return false;
      }
    }
    true
  }
}

impl<'a, T> Iterator for CursorIter<'a, T> {
  type Item = Cursor<'a, T>;

  fn next(&mut self) -> Option<Self::Item> {
    if self.exhausted {
      None
    } else {
      let out = self.cursor_head;
      if out == self.cursor_tail {
        self.exhausted = true;
      } else {
        self.cursor_head.move_next();
      }
      Some(out)
    }
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    (self.len(), Some(self.len()))
  }
}

impl<'a, T> ExactSizeIterator for CursorIter<'a, T> {
  fn len(&self) -> usize {
    let pos_head = self.cursor_head.position;
    let pos_tail = self.cursor_tail.position;
    if pos_head.position_id.0 <= pos_tail.position_id.0 {
      pos_tail.position_id.0 - pos_head.position_id.0 + 1
    } else {
      pos_head.size - pos_head.position_id.0 + pos_tail.position_id.0 + 1
    }
  }
}

impl<'a, T> DoubleEndedIterator for CursorIter<'a, T> {
  fn next_back(&mut self) -> Option<Self::Item> {
    if self.exhausted {
      None
    } else {
      let out = self.cursor_tail;
      if out == self.cursor_head {
        self.exhausted = true;
      } else {
        self.cursor_tail.move_next();
      }
      Some(out)
    }
  }
}