xitca_unsafe_collection/bound_queue/
stack.rs

1use core::{fmt, mem::MaybeUninit};
2
3use super::{Bounded, PushError, Queueable};
4
5pub struct StackQueue<T, const N: usize> {
6    inner: Bounded<[MaybeUninit<T>; N]>,
7}
8
9impl<T, const N: usize> Default for StackQueue<T, N> {
10    fn default() -> Self {
11        unimplemented!("please use StackQueue::new");
12    }
13}
14
15impl<T, const N: usize> StackQueue<T, N> {
16    #[inline]
17    pub const fn new() -> Self {
18        Self {
19            inner: Bounded {
20                queue: [const { MaybeUninit::uninit() }; N],
21                next: 0,
22                len: 0,
23            },
24        }
25    }
26
27    #[inline]
28    pub const fn is_empty(&self) -> bool {
29        self.inner.is_empty()
30    }
31
32    #[inline]
33    pub fn is_full(&self) -> bool {
34        self.inner.is_full()
35    }
36
37    #[inline]
38    pub const fn len(&self) -> usize {
39        self.inner.len()
40    }
41
42    #[inline]
43    pub fn front(&self) -> Option<&T> {
44        self.inner.front()
45    }
46
47    #[inline]
48    pub fn front_mut(&mut self) -> Option<&mut T> {
49        self.inner.front_mut()
50    }
51
52    #[inline]
53    pub fn push_back(&mut self, item: T) -> Result<(), PushError<T>> {
54        self.inner.push_back(item)
55    }
56
57    #[inline]
58    pub fn pop_front(&mut self) -> Option<T> {
59        self.inner.pop_front()
60    }
61
62    #[inline]
63    pub fn truncate(&mut self, n: usize) {
64        self.inner.truncate(n)
65    }
66
67    #[inline]
68    pub fn clear(&mut self) {
69        self.inner.clear();
70    }
71
72    #[inline]
73    pub fn iter(&self) -> Iter<'_, T, N> {
74        self.inner.iter()
75    }
76}
77
78pub type Iter<'a, T, const N: usize> = super::Iter<'a, [MaybeUninit<T>; N]>;
79
80impl<T, const N: usize> Queueable for [MaybeUninit<T>; N] {
81    type Item = T;
82
83    #[inline(always)]
84    fn capacity(&self) -> usize {
85        N
86    }
87
88    // SAFETY: see trait definition.
89    #[inline]
90    unsafe fn _get_unchecked(&self, idx: usize) -> &Self::Item {
91        self.get_unchecked(idx).assume_init_ref()
92    }
93
94    // SAFETY: see trait definition.
95    #[inline]
96    unsafe fn _get_mut_unchecked(&mut self, idx: usize) -> &mut Self::Item {
97        self.get_unchecked_mut(idx).assume_init_mut()
98    }
99
100    // SAFETY: see trait definition.
101    #[inline]
102    unsafe fn _read_unchecked(&mut self, idx: usize) -> Self::Item {
103        self.get_unchecked_mut(idx).assume_init_read()
104    }
105
106    // SAFETY: see trait definition.
107    #[inline]
108    unsafe fn _write_unchecked(&mut self, idx: usize, item: Self::Item) {
109        self.get_unchecked_mut(idx).write(item);
110    }
111}
112
113impl<T, const N: usize> fmt::Debug for StackQueue<T, N> {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        write!(f, "StackQueue<T, {N}>")
116    }
117}
118
119#[cfg(test)]
120mod test {
121    use super::*;
122
123    #[test]
124    fn iterate() {
125        let mut queue = StackQueue::<_, 5>::new();
126
127        queue.push_back("996").ok().unwrap();
128        queue.push_back("231").ok().unwrap();
129        queue.push_back("007").ok().unwrap();
130
131        let mut iter = queue.iter();
132
133        assert_eq!(iter.next(), Some(&"996"));
134        assert_eq!(iter.next(), Some(&"231"));
135        assert_eq!(iter.next(), Some(&"007"));
136        assert_eq!(iter.next(), None);
137
138        assert_eq!(queue.pop_front(), Some("996"));
139
140        let mut iter = queue.iter();
141
142        assert_eq!(iter.next(), Some(&"231"));
143        assert_eq!(iter.next(), Some(&"007"));
144        assert_eq!(iter.next(), None);
145    }
146
147    #[test]
148    fn cap() {
149        let mut queue = StackQueue::<_, 3>::new();
150
151        queue.push_back("996").ok().unwrap();
152        queue.push_back("231").ok().unwrap();
153        queue.push_back("007").ok().unwrap();
154
155        assert!(queue.push_back("123").is_err());
156
157        assert_eq!(queue.pop_front(), Some("996"));
158        queue.push_back("123").unwrap();
159        assert!(queue.push_back("123").is_err());
160
161        assert_eq!(queue.pop_front(), Some("231"));
162        assert_eq!(queue.pop_front(), Some("007"));
163        queue.push_back("123").unwrap();
164        queue.push_back("123").unwrap();
165        assert!(queue.push_back("123").is_err());
166    }
167
168    #[test]
169    fn front_mut() {
170        let mut queue = StackQueue::<_, 3>::new();
171
172        assert_eq!(None, queue.front_mut());
173
174        queue.push_back("996").ok().unwrap();
175        queue.push_back("231").ok().unwrap();
176        queue.push_back("007").ok().unwrap();
177
178        assert_eq!(Some(&mut "996"), queue.front_mut());
179
180        queue.pop_front();
181        assert_eq!(Some(&mut "231"), queue.front_mut());
182
183        queue.pop_front();
184        assert_eq!(Some(&mut "007"), queue.front_mut());
185
186        queue.pop_front();
187        assert_eq!(None, queue.front_mut());
188    }
189
190    #[test]
191    fn wrap() {
192        let mut queue = StackQueue::<_, 4>::new();
193
194        for i in 0..4 {
195            assert!(queue.push_back(i).is_ok());
196        }
197
198        assert!(queue.is_full());
199
200        assert!(queue.pop_front().is_some());
201        assert!(queue.pop_front().is_some());
202
203        assert!(queue.push_back(1).is_ok());
204
205        queue.clear();
206    }
207
208    #[test]
209    fn truncate() {
210        let mut queue = StackQueue::<_, 4>::new();
211
212        for i in 0..4 {
213            assert!(queue.push_back(i).is_ok());
214        }
215
216        queue.truncate(3);
217        assert!(queue.push_back(5).is_ok());
218        assert!(queue.is_full());
219
220        queue.truncate(0);
221        assert!(queue.is_empty());
222
223        for i in 0..4 {
224            assert!(queue.push_back(i).is_ok());
225        }
226
227        assert_eq!(queue.pop_front(), Some(0));
228        assert_eq!(queue.pop_front(), Some(1));
229
230        assert_eq!(queue.len(), 2);
231    }
232
233    #[test]
234    fn drop() {
235        extern crate alloc;
236
237        use alloc::sync::Arc;
238
239        let item = Arc::new(123);
240
241        {
242            let _queue = StackQueue::<u8, 3>::new();
243        }
244
245        {
246            let mut queue = StackQueue::<_, 3>::new();
247
248            queue.push_back(item.clone()).ok().unwrap();
249            queue.push_back(item.clone()).ok().unwrap();
250
251            assert_eq!(Arc::strong_count(&item), 3);
252        }
253
254        assert_eq!(Arc::strong_count(&item), 1);
255
256        {
257            let mut queue = StackQueue::<_, 3>::new();
258
259            queue.push_back(item.clone()).ok().unwrap();
260
261            assert_eq!(Arc::strong_count(&item), 2);
262        }
263
264        assert_eq!(Arc::strong_count(&item), 1);
265
266        {
267            let mut queue = StackQueue::<_, 3>::new();
268
269            queue.push_back(item.clone()).ok().unwrap();
270            queue.push_back(item.clone()).ok().unwrap();
271            queue.push_back(item.clone()).ok().unwrap();
272
273            assert_eq!(Arc::strong_count(&item), 4);
274        }
275
276        assert_eq!(Arc::strong_count(&item), 1);
277    }
278}