lobby_queue/
iter.rs

1//! Iterators for Lobby.
2
3use crate::Lobby;
4
5/// Immutable Lobby iterator.
6#[derive(Debug)]
7pub struct Iter<'a, T, const N: usize> {
8    inner: IterFull<'a, T, N>,
9}
10
11impl<'a, T, const N: usize> Iter<'a, T, N> {
12    /// Create a new Iter.
13    #[inline]
14    pub fn new(inner: &'a Lobby<T, N>) -> Self {
15        Self {
16            inner: IterFull { inner, idx: 0 },
17        }
18    }
19
20    /// Transforms this iterator into an `IterFull`.
21    #[inline]
22    pub fn with_full(self) -> IterFull<'a, T, N> {
23        self.inner
24    }
25}
26
27impl<'a, T, const N: usize> Iterator for Iter<'a, T, N> {
28    type Item = &'a T;
29
30    #[inline]
31    fn next(&mut self) -> Option<Self::Item> {
32        self.inner.next().and_then(|v| v)
33    }
34}
35
36/// Immutable Lobby iterator that yields `N` items for each space in the Lobby.
37#[derive(Debug)]
38pub struct IterFull<'a, T, const N: usize> {
39    inner: &'a Lobby<T, N>,
40
41    idx: usize,
42}
43
44impl<'a, T, const N: usize> Iterator for IterFull<'a, T, N> {
45    type Item = Option<&'a T>;
46
47    #[inline]
48    fn next(&mut self) -> Option<Self::Item> {
49        self.idx += 1;
50        if self.idx > N {
51            None
52        } else {
53            Some(self.inner.nth(self.idx - 1))
54        }
55    }
56}
57
58/// Mutable Lobby iterator.
59#[derive(Debug)]
60pub struct IterMut<'a, T, const N: usize> {
61    inner: IterMutFull<'a, T, N>,
62}
63
64impl<'a, T, const N: usize> IterMut<'a, T, N> {
65    /// Create a new IterMut.
66    #[inline]
67    pub fn new(inner: &'a mut Lobby<T, N>) -> Self {
68        Self {
69            inner: IterMutFull {
70                inner: &mut inner.arr,
71                idx: 0,
72            },
73        }
74    }
75
76    /// Transforms this iterator into an [`IterMutFull`].
77    #[inline]
78    pub fn with_full(self) -> IterMutFull<'a, T, N> {
79        self.inner
80    }
81}
82
83impl<'a, T, const N: usize> Iterator for IterMut<'a, T, N> {
84    type Item = &'a mut T;
85
86    #[inline]
87    fn next(&mut self) -> Option<Self::Item> {
88        self.inner.next().and_then(|v| v)
89    }
90}
91
92/// Mutable Lobby iterator that yields `N` items for each space in the Lobby.
93#[derive(Debug)]
94pub struct IterMutFull<'a, T, const N: usize> {
95    inner: &'a mut [Option<T>; N],
96
97    idx: usize,
98}
99
100impl<'a, T, const N: usize> Iterator for IterMutFull<'a, T, N> {
101    type Item = Option<&'a mut T>;
102
103    #[inline]
104    fn next(&mut self) -> Option<Self::Item> {
105        if self.idx >= N {
106            None
107        } else {
108            // SAFETY: self.idx is guaranteed to be within bounds.
109            let v = (unsafe { &mut *self.inner.as_mut_ptr().add(self.idx) }).as_mut();
110            self.idx += 1;
111            Some(v)
112        }
113    }
114}
115
116/// Owning Lobby iterator.
117#[derive(Debug)]
118pub struct IntoIter<T, const N: usize> {
119    inner: IntoIterFull<T, N>,
120}
121
122impl<'a, T, const N: usize> IntoIter<T, N> {
123    /// Create a new IterMut.
124    #[inline]
125    pub fn new(inner: Lobby<T, N>) -> Self {
126        Self {
127            inner: IntoIterFull { inner, idx: 0 },
128        }
129    }
130
131    /// Transforms this iterator into an [`IntoIterFull`].
132    #[inline]
133    pub fn with_full(self) -> IntoIterFull<T, N> {
134        self.inner
135    }
136}
137
138impl<T, const N: usize> Iterator for IntoIter<T, N> {
139    type Item = T;
140
141    #[inline]
142    fn next(&mut self) -> Option<Self::Item> {
143        self.inner.next().and_then(|v| v)
144    }
145}
146
147/// Owning Lobby iterator that yields `N` items for each space in the Lobby.
148#[derive(Debug)]
149pub struct IntoIterFull<T, const N: usize> {
150    inner: Lobby<T, N>,
151
152    idx: usize,
153}
154
155impl<T, const N: usize> Iterator for IntoIterFull<T, N> {
156    type Item = Option<T>;
157
158    #[inline]
159    fn next(&mut self) -> Option<Self::Item> {
160        if self.idx >= N {
161            None
162        } else {
163            self.idx += 1;
164            Some(self.inner.shift())
165        }
166    }
167}