Skip to main content

int_interval/
res.rs

1use core::iter::FusedIterator;
2
3#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
4pub enum OneTwo<T> {
5    One(T),
6    Two(T, T),
7}
8
9#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
10pub enum ZeroOneTwo<T> {
11    Zero,
12    One(T),
13    Two(T, T),
14}
15
16/// Owned iterator for `OneTwo<T>` and `ZeroOneTwo<T>`.
17#[derive(Clone, Debug)]
18pub struct IntoIter<T> {
19    items: [Option<T>; 2],
20    front: usize,
21    back: usize,
22}
23
24impl<T> IntoIter<T> {
25    #[inline]
26    fn zero() -> Self {
27        Self {
28            items: [None, None],
29            front: 0,
30            back: 0,
31        }
32    }
33
34    #[inline]
35    fn one(value: T) -> Self {
36        Self {
37            items: [Some(value), None],
38            front: 0,
39            back: 1,
40        }
41    }
42
43    #[inline]
44    fn two(first: T, second: T) -> Self {
45        Self {
46            items: [Some(first), Some(second)],
47            front: 0,
48            back: 2,
49        }
50    }
51}
52
53impl<T> Iterator for IntoIter<T> {
54    type Item = T;
55
56    #[inline]
57    fn next(&mut self) -> Option<Self::Item> {
58        if self.front == self.back {
59            return None;
60        }
61
62        let index = self.front;
63        self.front += 1;
64        self.items[index].take()
65    }
66
67    #[inline]
68    fn size_hint(&self) -> (usize, Option<usize>) {
69        let len = self.len();
70        (len, Some(len))
71    }
72}
73
74impl<T> DoubleEndedIterator for IntoIter<T> {
75    #[inline]
76    fn next_back(&mut self) -> Option<Self::Item> {
77        if self.front == self.back {
78            return None;
79        }
80
81        self.back -= 1;
82        self.items[self.back].take()
83    }
84}
85
86impl<T> ExactSizeIterator for IntoIter<T> {
87    #[inline]
88    fn len(&self) -> usize {
89        self.back - self.front
90    }
91}
92
93impl<T> FusedIterator for IntoIter<T> {}
94
95impl<T> IntoIterator for OneTwo<T> {
96    type Item = T;
97    type IntoIter = IntoIter<T>;
98
99    #[inline]
100    fn into_iter(self) -> Self::IntoIter {
101        match self {
102            Self::One(value) => IntoIter::one(value),
103            Self::Two(first, second) => IntoIter::two(first, second),
104        }
105    }
106}
107
108impl<T> IntoIterator for ZeroOneTwo<T> {
109    type Item = T;
110    type IntoIter = IntoIter<T>;
111
112    #[inline]
113    fn into_iter(self) -> Self::IntoIter {
114        match self {
115            Self::Zero => IntoIter::zero(),
116            Self::One(value) => IntoIter::one(value),
117            Self::Two(first, second) => IntoIter::two(first, second),
118        }
119    }
120}
121
122#[cfg(test)]
123mod tests_for_into_iter;