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