Skip to main content

int_intervals/interval/
res.rs

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