1use crate::error::CapacityError;
2use core::mem::{MaybeUninit, replace, transmute};
3
4#[derive(Debug)]
6pub struct ArrayQueue<T, const N: usize> {
7 array: [MaybeUninit<T>; N],
8 start: usize,
9 length: usize,
10}
11
12impl<T, const N: usize> ArrayQueue<T, N> {
13 pub const fn new() -> Self {
15 Self {
16 array: [const { MaybeUninit::uninit() }; N],
17 start: 0,
18 length: 0,
19 }
20 }
21
22 pub const fn first(&self) -> Option<&T> {
24 self.element(0)
25 }
26
27 pub const fn first_mut(&mut self) -> Option<&mut T> {
29 self.element_mut(0)
30 }
31
32 pub const fn last(&self) -> Option<&T> {
34 if self.is_empty() {
35 None
36 } else {
37 self.element(self.length - 1)
38 }
39 }
40
41 pub const fn last_mut(&mut self) -> Option<&mut T> {
43 if self.is_empty() {
44 None
45 } else {
46 self.element_mut(self.length - 1)
47 }
48 }
49
50 const fn element(&self, index: usize) -> Option<&T> {
51 if index < self.length {
52 let x = &self.array[self.index(index)];
53
54 Some(unsafe { x.assume_init_ref() })
56 } else {
57 None
58 }
59 }
60
61 const fn element_mut(&mut self, index: usize) -> Option<&mut T> {
62 if index < self.length {
63 let x = &mut self.array[self.index(index)];
64
65 Some(unsafe { x.assume_init_mut() })
67 } else {
68 None
69 }
70 }
71
72 pub fn push_front(&mut self, x: T) -> Result<(), CapacityError> {
74 if self.is_full() {
75 return Err(CapacityError);
76 }
77
78 self.start = self.index(N - 1);
79 self.array[self.start] = MaybeUninit::new(x);
80 self.length += 1;
81
82 Ok(())
83 }
84
85 pub fn push_back(&mut self, x: T) -> Result<(), CapacityError> {
87 if self.is_full() {
88 return Err(CapacityError);
89 }
90
91 self.array[self.index(self.length)] = MaybeUninit::new(x);
92 self.length += 1;
93
94 Ok(())
95 }
96
97 pub const fn pop_front(&mut self) -> Option<T> {
99 if self.is_empty() {
100 None
101 } else {
102 let x = replace(&mut self.array[self.index(0)], MaybeUninit::uninit());
103 self.start = self.index(1);
104 self.length -= 1;
105
106 Some(unsafe { x.assume_init() })
108 }
109 }
110
111 pub const fn pop_back(&mut self) -> Option<T> {
113 if self.is_empty() {
114 None
115 } else {
116 let x = replace(
117 &mut self.array[self.index(self.length - 1)],
118 MaybeUninit::uninit(),
119 );
120 self.length -= 1;
121
122 Some(unsafe { x.assume_init() })
124 }
125 }
126
127 pub const fn len(&self) -> usize {
129 self.length
130 }
131
132 pub const fn is_empty(&self) -> bool {
134 self.len() == 0
135 }
136
137 pub const fn is_full(&self) -> bool {
139 self.len() == N
140 }
141
142 const fn index(&self, index: usize) -> usize {
143 (self.start + index) % N
144 }
145}
146
147impl<T: Clone, const N: usize> Clone for ArrayQueue<T, N> {
148 fn clone(&self) -> Self {
149 let mut queue = Self::new();
150
151 for x in self {
152 queue.push_back(x.clone()).unwrap();
153 }
154
155 queue
156 }
157}
158
159impl<T, const N: usize> Default for ArrayQueue<T, N> {
160 fn default() -> Self {
161 Self::new()
162 }
163}
164
165impl<T, const N: usize> Drop for ArrayQueue<T, N> {
166 fn drop(&mut self) {
167 #[expect(clippy::redundant_pattern_matching)]
168 while let Some(_) = self.pop_back() {}
169 }
170}
171
172#[derive(Debug)]
173pub struct ArrayQueueIterator<'a, T, const N: usize> {
174 queue: &'a ArrayQueue<T, N>,
175 first: usize,
176 last: usize,
177}
178
179impl<'a, T, const N: usize> ArrayQueueIterator<'a, T, N> {
180 const fn is_exhausted(&self) -> bool {
181 self.first >= self.last
182 }
183}
184
185impl<'a, T, const N: usize> IntoIterator for &'a ArrayQueue<T, N> {
186 type Item = &'a T;
187 type IntoIter = ArrayQueueIterator<'a, T, N>;
188
189 fn into_iter(self) -> Self::IntoIter {
190 ArrayQueueIterator {
191 queue: self,
192 first: 0,
193 last: self.len(),
194 }
195 }
196}
197
198impl<'a, T, const N: usize> Iterator for ArrayQueueIterator<'a, T, N> {
199 type Item = &'a T;
200
201 fn next(&mut self) -> Option<Self::Item> {
202 if self.is_exhausted() {
203 return None;
204 }
205
206 let x = self.queue.element(self.first);
207 self.first += x.is_some() as usize;
208 x
209 }
210}
211
212impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueIterator<'a, T, N> {
213 fn next_back(&mut self) -> Option<Self::Item> {
214 if self.is_exhausted() {
215 return None;
216 }
217
218 let x = self.queue.element(self.last - 1);
219 self.last -= x.is_some() as usize;
220 x
221 }
222}
223
224#[derive(Debug)]
225pub struct ArrayQueueMutIterator<'a, T, const N: usize> {
226 queue: &'a mut ArrayQueue<T, N>,
227 first: usize,
228 last: usize,
229}
230
231impl<'a, T, const N: usize> ArrayQueueMutIterator<'a, T, N> {
232 const fn is_exhausted(&self) -> bool {
233 self.first >= self.last
234 }
235}
236
237impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayQueue<T, N> {
238 type Item = &'a mut T;
239 type IntoIter = ArrayQueueMutIterator<'a, T, N>;
240
241 fn into_iter(self) -> Self::IntoIter {
242 let last = self.len();
243
244 ArrayQueueMutIterator {
245 queue: self,
246 first: 0,
247 last,
248 }
249 }
250}
251
252impl<'a, T, const N: usize> Iterator for ArrayQueueMutIterator<'a, T, N> {
253 type Item = &'a mut T;
254
255 fn next(&mut self) -> Option<Self::Item> {
256 if self.is_exhausted() {
257 return None;
258 }
259
260 let x = self.queue.element_mut(self.first);
261 self.first += x.is_some() as usize;
262 x.map(|x| unsafe { transmute(x) })
264 }
265}
266
267impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueMutIterator<'a, T, N> {
268 fn next_back(&mut self) -> Option<Self::Item> {
269 if self.is_exhausted() {
270 return None;
271 }
272
273 let x = self.queue.element_mut(self.last - 1);
274 self.last -= x.is_some() as usize;
275 x.map(|x| unsafe { transmute(x) })
277 }
278}
279
280#[cfg(test)]
281mod test {
282 use super::*;
283 use alloc::boxed::Box;
284
285 #[test]
286 fn new() {
287 ArrayQueue::<usize, 1>::new();
288 ArrayQueue::<usize, 2>::new();
289 }
290
291 #[test]
292 fn first_and_last() {
293 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
294
295 assert_eq!(a.first(), None);
296 assert_eq!(a.first_mut(), None);
297 assert_eq!(a.last(), None);
298 assert_eq!(a.last_mut(), None);
299
300 assert!(a.push_back(1).is_ok());
301
302 assert_eq!(a.first(), Some(&1));
303 assert_eq!(a.first_mut(), Some(&mut 1));
304 assert_eq!(a.last(), Some(&1));
305 assert_eq!(a.last_mut(), Some(&mut 1));
306
307 assert!(a.push_back(2).is_ok());
308
309 assert_eq!(a.first(), Some(&1));
310 assert_eq!(a.first_mut(), Some(&mut 1));
311 assert_eq!(a.last(), Some(&2));
312 assert_eq!(a.last_mut(), Some(&mut 2));
313 }
314
315 #[test]
316 fn push_back() {
317 let mut a: ArrayQueue<usize, 1> = ArrayQueue::new();
318
319 assert_eq!(a.len(), 0);
320 assert!(a.push_back(42).is_ok());
321 assert_eq!(a.len(), 1);
322 assert_eq!(a.push_back(42), Err(CapacityError));
323 assert_eq!(a.len(), 1);
324
325 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
326
327 assert_eq!(a.len(), 0);
328 assert!(a.push_back(42).is_ok());
329 assert_eq!(a.len(), 1);
330 assert!(a.push_back(42).is_ok());
331 assert_eq!(a.len(), 2);
332 assert_eq!(a.push_back(42), Err(CapacityError));
333 assert_eq!(a.len(), 2);
334 }
335
336 #[test]
337 fn push_front() {
338 let mut a: ArrayQueue<usize, 1> = ArrayQueue::new();
339
340 assert_eq!(a.len(), 0);
341 assert!(a.push_front(42).is_ok());
342 assert_eq!(a.len(), 1);
343 assert_eq!(a.push_front(42), Err(CapacityError));
344 assert_eq!(a.len(), 1);
345
346 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
347
348 assert_eq!(a.len(), 0);
349 assert!(a.push_front(1).is_ok());
350 assert_eq!(a.first(), Some(&1));
351 assert_eq!(a.last(), Some(&1));
352 assert_eq!(a.len(), 1);
353 assert!(a.push_front(2).is_ok());
354 assert_eq!(a.first(), Some(&2));
355 assert_eq!(a.last(), Some(&1));
356 assert_eq!(a.len(), 2);
357 assert_eq!(a.push_front(3), Err(CapacityError));
358 assert_eq!(a.len(), 2);
359 }
360
361 #[test]
362 fn pop_back() {
363 let mut a: ArrayQueue<usize, 1> = ArrayQueue::new();
364
365 assert!(a.push_back(42).is_ok());
366
367 assert_eq!(a.pop_back(), Some(42));
368 assert_eq!(a.len(), 0);
369
370 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
371
372 assert!(a.push_back(123).is_ok());
373 assert!(a.push_back(42).is_ok());
374
375 assert_eq!(a.pop_back(), Some(42));
376 assert_eq!(a.first(), Some(&123));
377 assert_eq!(a.last(), Some(&123));
378 assert_eq!(a.len(), 1);
379 assert_eq!(a.pop_back(), Some(123));
380 assert_eq!(a.len(), 0);
381 }
382
383 #[test]
384 fn pop_front() {
385 let mut a: ArrayQueue<usize, 1> = ArrayQueue::new();
386
387 assert!(a.push_back(42).is_ok());
388
389 assert_eq!(a.pop_front(), Some(42));
390 assert_eq!(a.len(), 0);
391
392 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
393
394 assert!(a.push_back(123).is_ok());
395 assert!(a.push_back(42).is_ok());
396
397 assert_eq!(a.pop_front(), Some(123));
398 assert_eq!(a.first(), Some(&42));
399 assert_eq!(a.last(), Some(&42));
400 assert_eq!(a.len(), 1);
401 assert_eq!(a.pop_front(), Some(42));
402 assert_eq!(a.len(), 0);
403 }
404
405 #[test]
406 fn push_and_pop_across_edges() {
407 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
408
409 assert!(a.push_back(1).is_ok());
410 assert!(a.push_back(2).is_ok());
411
412 for i in 3..64 {
413 assert_eq!(a.pop_front(), Some(i - 2));
414 assert_eq!(a.len(), 1);
415 assert!(a.push_back(i).is_ok());
416 assert_eq!(a.len(), 2);
417 }
418 }
419
420 #[test]
421 fn is_empty() {
422 let a: ArrayQueue<usize, 1> = ArrayQueue::new();
423 assert!(a.is_empty());
424
425 let a: ArrayQueue<usize, 2> = ArrayQueue::new();
426 assert!(a.is_empty());
427 }
428
429 #[test]
430 fn is_full() {
431 let mut a: ArrayQueue<usize, 1> = ArrayQueue::new();
432 assert!(a.push_back(0).is_ok());
433 assert!(a.is_full());
434
435 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
436 assert!(a.push_back(0).is_ok());
437 assert!(a.push_back(0).is_ok());
438 assert!(a.is_full());
439 }
440
441 #[test]
442 fn iterator() {
443 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
444
445 assert!(a.push_back(0).is_ok());
446 assert!(a.push_back(1).is_ok());
447
448 for (i, e) in a.into_iter().enumerate() {
449 assert_eq!(*e, i);
450 }
451 }
452
453 #[test]
454 fn iterator_across_edges() {
455 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
456
457 assert!(a.push_back(42).is_ok());
458 a.pop_front();
459 assert!(a.push_back(0).is_ok());
460 assert!(a.push_back(1).is_ok());
461
462 for (i, e) in a.into_iter().enumerate() {
463 assert_eq!(*e, i);
464 }
465 }
466
467 #[test]
468 fn iterate_forward_and_backward() {
469 let mut a = ArrayQueue::<usize, 2>::new();
470
471 assert!(a.push_back(0).is_ok());
472 assert!(a.push_back(1).is_ok());
473
474 let mut i = a.into_iter();
475
476 assert_eq!(i.next(), Some(&0));
477 assert_eq!(i.next_back(), Some(&1));
478 assert_eq!(i.next(), None);
479 assert_eq!(i.next_back(), None);
480 }
481
482 #[test]
483 fn iterate_forward_and_backward_mutable() {
484 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
485
486 assert!(a.push_back(0).is_ok());
487 assert!(a.push_back(1).is_ok());
488
489 let mut i = (&mut a).into_iter();
490
491 assert_eq!(i.next(), Some(&mut 0));
492 assert_eq!(i.next_back(), Some(&mut 1));
493 assert_eq!(i.next(), None);
494 assert_eq!(i.next_back(), None);
495 }
496
497 #[test]
498 fn iterate_empty_queue() {
499 let a = ArrayQueue::<usize, 0>::new();
500
501 for _ in a.into_iter() {}
502 }
503
504 #[test]
505 fn iterator_mut() {
506 let mut a: ArrayQueue<usize, 2> = ArrayQueue::new();
507
508 assert!(a.push_back(0).is_ok());
509 assert!(a.push_back(1).is_ok());
510
511 for (i, e) in (&mut a).into_iter().enumerate() {
512 assert_eq!(*e, i);
513 *e = 42;
514 }
515 }
516
517 #[test]
518 fn reference_elements() {
519 let mut a: ArrayQueue<Box<usize>, 2> = ArrayQueue::new();
520 assert!(a.push_back(Box::new(42)).is_ok());
521 assert!(a.push_front(Box::new(42)).is_ok());
522 }
523
524 #[test]
525 fn clone() {
526 let mut a: ArrayQueue<Box<usize>, 32> = ArrayQueue::new();
527
528 for _ in 0..32 {
529 assert!(a.push_back(Box::new(42)).is_ok());
530 }
531
532 let _ = a.clone();
533 }
534
535 static mut FOO_SUM: usize = 0;
536
537 #[derive(Clone)]
538 struct Foo;
539
540 impl Drop for Foo {
541 fn drop(&mut self) {
542 unsafe {
543 FOO_SUM += 1;
544 }
545 }
546 }
547
548 #[test]
549 fn no_drops_of_elements_on_push_back() {
550 assert_eq!(unsafe { FOO_SUM }, 0);
551
552 let mut a: ArrayQueue<Foo, 42> = ArrayQueue::new();
553
554 for _ in 0..17 {
555 assert!(a.push_back(Foo).is_ok());
556 }
557
558 assert_eq!(unsafe { FOO_SUM }, 0);
559
560 drop(a);
561
562 assert_eq!(unsafe { FOO_SUM }, 17);
563 }
564
565 static mut BAR_SUM: usize = 0;
566
567 #[derive(Clone)]
568 struct Bar;
569
570 impl Drop for Bar {
571 fn drop(&mut self) {
572 unsafe {
573 BAR_SUM += 1;
574 }
575 }
576 }
577
578 #[test]
579 fn drops_of_elements_on_pop_back() {
580 assert_eq!(unsafe { BAR_SUM }, 0);
581
582 let mut a: ArrayQueue<Bar, 32> = ArrayQueue::new();
583
584 for _ in 0..32 {
585 assert!(a.push_back(Bar).is_ok());
586 }
587
588 assert_eq!(unsafe { BAR_SUM }, 0);
589
590 for _ in 0..32 {
591 assert!(a.pop_back().is_some());
592 }
593
594 assert_eq!(unsafe { BAR_SUM }, 32);
595
596 drop(a);
597
598 assert_eq!(unsafe { BAR_SUM }, 32);
599 }
600
601 #[test]
602 fn pop_back_from_middle() {
603 const LENGTH: usize = 42;
604 const MIDDLE: usize = 17;
605
606 let mut xs = ArrayQueue::<Box<usize>, LENGTH>::new();
607
608 for x in 0..LENGTH {
609 assert!(xs.push_back(Box::new(x)).is_ok());
610 }
611
612 for _ in 0..MIDDLE {
613 xs.pop_front();
614 }
615
616 for x in LENGTH..MIDDLE {
617 assert_eq!(xs.pop_back(), Some(Box::new(x - 1)));
618 }
619 }
620}