xitca_unsafe_collection/bound_queue/
stack.rs1use 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 #[inline]
90 unsafe fn _get_unchecked(&self, idx: usize) -> &Self::Item {
91 self.get_unchecked(idx).assume_init_ref()
92 }
93
94 #[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 #[inline]
102 unsafe fn _read_unchecked(&mut self, idx: usize) -> Self::Item {
103 self.get_unchecked_mut(idx).assume_init_read()
104 }
105
106 #[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}