my_ecs/ds/arr.rs
1//! Provides fixed-size array data types.
2
3use std::{
4 alloc::Layout,
5 iter::Chain,
6 mem,
7 mem::MaybeUninit,
8 ops::{Index, IndexMut},
9 ptr, slice,
10};
11
12/// An array type like `[T; N]`, but providing some methods of [`Vec`].
13#[derive(Debug)]
14pub struct Array<T, const N: usize> {
15 data: [MaybeUninit<T>; N],
16 len: usize,
17}
18
19impl<T, const N: usize> Array<T, N> {
20 /// Creates a new empty [`Array`].
21 ///
22 /// # Examples
23 ///
24 /// ```
25 /// use my_ecs::ds::Array;
26 ///
27 /// let arr = Array::<i32, 2>::new();
28 /// ```
29 pub const fn new() -> Self {
30 Self {
31 data: [const { MaybeUninit::uninit() }; N],
32 len: 0,
33 }
34 }
35
36 /// Returns capacity, which is `N`.
37 ///
38 /// # Examples
39 ///
40 /// ```
41 /// use my_ecs::ds::Array;
42 ///
43 /// let arr = Array::<i32, 2>::new();
44 /// assert_eq!(arr.capacity(), 2);
45 /// ```
46 pub const fn capacity(&self) -> usize {
47 N
48 }
49
50 /// Returns number of items.
51 ///
52 /// # Examples
53 ///
54 /// ```
55 /// use my_ecs::ds::Array;
56 ///
57 /// let mut arr = Array::<i32, 2>::new();
58 /// arr.push(0);
59 /// assert_eq!(arr.len(), 1);
60 /// ```
61 pub const fn len(&self) -> usize {
62 self.len
63 }
64
65 /// Returns true if the array is empty.
66 ///
67 /// # Examples
68 ///
69 /// ```
70 /// use my_ecs::ds::Array;
71 ///
72 /// let arr = Array::<i32, 2>::new();
73 /// assert!(arr.is_empty());
74 /// ```
75 pub const fn is_empty(&self) -> bool {
76 self.len == 0
77 }
78
79 /// Returns true if the array contains `N` items.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// use my_ecs::ds::Array;
85 ///
86 /// let mut arr = Array::<i32, 2>::new();
87 /// arr.push(0);
88 /// arr.push(1);
89 /// assert!(arr.is_full());
90 /// ```
91 pub const fn is_full(&self) -> bool {
92 self.len == N
93 }
94
95 /// Retrieves a shared reference to an item at the given index.
96 ///
97 /// # Examples
98 ///
99 /// ```
100 /// use my_ecs::ds::Array;
101 ///
102 /// let mut arr = Array::<i32, 2>::new();
103 /// arr.push(0);
104 /// assert_eq!(arr.get(0), Some(&0));
105 /// ```
106 pub fn get(&self, index: usize) -> Option<&T> {
107 if index < self.len() {
108 // Safety: Checked the index.
109 unsafe { Some(self.data[index].assume_init_ref()) }
110 } else {
111 None
112 }
113 }
114
115 /// Retrieves a mutable reference to an item at the given index.
116 ///
117 /// # Examples
118 ///
119 /// ```
120 /// use my_ecs::ds::Array;
121 ///
122 /// let mut arr = Array::<i32, 2>::new();
123 /// arr.push(0);
124 /// assert_eq!(arr.get_mut(0), Some(&mut 0));
125 /// ```
126 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
127 if index < self.len() {
128 // Safety: Checked the index.
129 unsafe { Some(self.data[index].assume_init_mut()) }
130 } else {
131 None
132 }
133 }
134
135 /// Returns iterator traversing all items.
136 ///
137 /// # Examples
138 ///
139 /// ```
140 /// use my_ecs::ds::Array;
141 ///
142 /// let mut arr = Array::<i32, 2>::new();
143 /// arr.push(0);
144 /// arr.push(1);
145 /// for item in arr.iter() {
146 /// println!("{item}");
147 /// }
148 /// ```
149 pub fn iter(&self) -> slice::Iter<'_, T> {
150 self.as_slice().iter()
151 }
152
153 /// Returns mutable iterator traversing all items.
154 ///
155 /// # Examples
156 ///
157 /// ```
158 /// use my_ecs::ds::Array;
159 ///
160 /// let mut arr = Array::<i32, 2>::new();
161 /// arr.push(0);
162 /// arr.push(1);
163 /// for item in arr.iter_mut() {
164 /// *item += 1;
165 /// }
166 /// ```
167 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
168 self.as_mut_slice().iter_mut()
169 }
170
171 /// Returns `&[T]` from the array.
172 ///
173 /// # Examples
174 ///
175 /// ```
176 /// use my_ecs::ds::Array;
177 ///
178 /// let arr = Array::<i32, 2>::new();
179 /// let slice: &[i32] = arr.as_slice();
180 /// ```
181 pub fn as_slice(&self) -> &[T] {
182 debug_assert_eq!(
183 Layout::new::<[MaybeUninit<T>; N]>(),
184 Layout::new::<[T; N]>()
185 );
186
187 unsafe {
188 let data = self.data.as_ptr() as *const T;
189 let len = self.len();
190 slice::from_raw_parts(data, len)
191 }
192 }
193
194 /// Returns `&mut [T]` from the array.
195 ///
196 /// # Examples
197 ///
198 /// ```
199 /// use my_ecs::ds::Array;
200 ///
201 /// let mut arr = Array::<i32, 2>::new();
202 /// let slice: &mut [i32] = arr.as_mut_slice();
203 /// ```
204 pub fn as_mut_slice(&mut self) -> &mut [T] {
205 debug_assert_eq!(
206 Layout::new::<[MaybeUninit<T>; N]>(),
207 Layout::new::<[T; N]>()
208 );
209
210 unsafe {
211 let data = self.data.as_ptr() as *mut T;
212 let len = self.len();
213 slice::from_raw_parts_mut(data, len)
214 }
215 }
216
217 /// Removes all items in the array.
218 ///
219 /// # Examples
220 ///
221 /// ```
222 /// use my_ecs::ds::Array;
223 ///
224 /// let mut arr = Array::<i32, 2>::new();
225 /// arr.push(0);
226 /// arr.clear();
227 /// assert!(arr.is_empty());
228 /// ```
229 pub fn clear(&mut self) {
230 self.drop_in_place();
231 self.len = 0;
232 }
233
234 /// Appends a given item at the end of the array.
235 ///
236 /// # Examples
237 ///
238 /// ```
239 /// use my_ecs::ds::Array;
240 ///
241 /// let mut arr = Array::<i32, 2>::new();
242 /// arr.push(0);
243 /// ```
244 pub fn push(&mut self, value: T) -> bool {
245 if !self.is_full() {
246 let tail = self.len();
247 self.data[tail].write(value);
248 self.len += 1;
249 true
250 } else {
251 false
252 }
253 }
254
255 /// Takes out an item from the end of the array.
256 ///
257 /// # Examples
258 ///
259 /// ```
260 /// use my_ecs::ds::Array;
261 ///
262 /// let mut arr = Array::<i32, 2>::new();
263 /// arr.push(0);
264 /// arr.push(1);
265 /// assert_eq!(arr.pop(), Some(1));
266 /// assert_eq!(arr.pop(), Some(0));
267 /// ```
268 pub fn pop(&mut self) -> Option<T> {
269 if !self.is_empty() {
270 self.len -= 1;
271 let tail = self.len();
272 // Safety: It's not empty, so data[tail] must have been initialized.
273 unsafe { Some(self.data[tail].assume_init_read()) }
274 } else {
275 None
276 }
277 }
278
279 /// Returns shared reference to the last item.
280 ///
281 /// # Examples
282 ///
283 /// ```
284 /// use my_ecs::ds::Array;
285 ///
286 /// let mut arr = Array::<i32, 2>::new();
287 /// arr.push(0);
288 /// arr.push(1);
289 /// assert_eq!(arr.back(), Some(&1));
290 /// ```
291 pub fn back(&self) -> Option<&T> {
292 if !self.is_empty() {
293 let index = self.len() - 1;
294 // Safety: It's not empty, so data[index] must have been initialized.
295 unsafe { Some(self.data[index].assume_init_ref()) }
296 } else {
297 None
298 }
299 }
300
301 /// Returns shared reference to the first item.
302 ///
303 /// # Examples
304 ///
305 /// ```
306 /// use my_ecs::ds::Array;
307 ///
308 /// let mut arr = Array::<i32, 2>::new();
309 /// arr.push(0);
310 /// arr.push(1);
311 /// assert_eq!(arr.front(), Some(&0));
312 /// ```
313 pub fn front(&self) -> Option<&T> {
314 if !self.is_empty() {
315 let index = 0;
316 // Safety: It's not empty, so data[index] must have been initialized.
317 unsafe { Some(self.data[index].assume_init_ref()) }
318 } else {
319 None
320 }
321 }
322
323 fn drop_in_place(&mut self) {
324 let slice = self.as_mut_slice();
325
326 unsafe { ptr::drop_in_place(slice as *mut _) };
327 }
328}
329
330impl<T, const N: usize> Default for Array<T, N> {
331 fn default() -> Self {
332 Self::new()
333 }
334}
335
336impl<T, const N: usize> Drop for Array<T, N> {
337 fn drop(&mut self) {
338 if mem::needs_drop::<T>() {
339 self.drop_in_place();
340 }
341 }
342}
343
344impl<T, const N: usize> Index<usize> for Array<T, N> {
345 type Output = T;
346
347 fn index(&self, index: usize) -> &Self::Output {
348 self.get(index).expect("Out of bounds access")
349 }
350}
351
352impl<T, const N: usize> IndexMut<usize> for Array<T, N> {
353 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
354 self.get_mut(index).expect("Out of bounds access")
355 }
356}
357
358/// An array type like `[T; N]`, but providing some methods of
359/// [`VecDeque`](std::collections::VecDeque).
360#[derive(Debug)]
361pub struct ArrayDeque<T, const N: usize> {
362 data: [MaybeUninit<T>; N],
363 head: usize,
364 len: usize,
365}
366
367impl<T, const N: usize> ArrayDeque<T, N> {
368 /// Creates a new empty [`ArrayDeque`].
369 ///
370 /// # Examples
371 ///
372 /// ```
373 /// use my_ecs::ds::ArrayDeque;
374 ///
375 /// let arr = ArrayDeque::<i32, 2>::new();
376 /// ```
377 pub const fn new() -> Self {
378 Self {
379 data: [const { MaybeUninit::uninit() }; N],
380 head: 0,
381 len: 0,
382 }
383 }
384
385 /// Returns capacity, which is `N`.
386 ///
387 /// # Examples
388 ///
389 /// ```
390 /// use my_ecs::ds::ArrayDeque;
391 ///
392 /// let arr = ArrayDeque::<i32, 2>::new();
393 /// assert_eq!(arr.capacity(), 2);
394 /// ```
395 pub const fn capacity(&self) -> usize {
396 N
397 }
398
399 /// Returns number of items.
400 ///
401 /// # Examples
402 ///
403 /// ```
404 /// use my_ecs::ds::ArrayDeque;
405 ///
406 /// let mut arr = ArrayDeque::<i32, 2>::new();
407 /// arr.push_back(0);
408 /// assert_eq!(arr.len(), 1);
409 /// ```
410 pub const fn len(&self) -> usize {
411 self.len
412 }
413
414 /// Returns true if the array is empty.
415 ///
416 /// # Examples
417 ///
418 /// ```
419 /// use my_ecs::ds::ArrayDeque;
420 ///
421 /// let arr = ArrayDeque::<i32, 2>::new();
422 /// assert!(arr.is_empty());
423 /// ```
424 pub const fn is_empty(&self) -> bool {
425 self.len == 0
426 }
427
428 /// Returns true if the array contains `N` items.
429 ///
430 /// # Examples
431 ///
432 /// ```
433 /// use my_ecs::ds::ArrayDeque;
434 ///
435 /// let mut arr = ArrayDeque::<i32, 2>::new();
436 /// arr.push_back(0);
437 /// arr.push_back(1);
438 /// assert!(arr.is_full());
439 /// ```
440 pub const fn is_full(&self) -> bool {
441 self.len == N
442 }
443
444 /// Retrieves a shared reference to an item at the given index.
445 ///
446 /// # Examples
447 ///
448 /// ```
449 /// use my_ecs::ds::ArrayDeque;
450 ///
451 /// let mut arr = ArrayDeque::<i32, 2>::new();
452 /// arr.push_back(0);
453 /// arr.push_front(1);
454 /// assert_eq!(arr.get(1), Some(&0));
455 /// ```
456 pub fn get(&self, index: usize) -> Option<&T> {
457 if index < self.len() {
458 let offset = self.offset(index);
459 // Safety: Checked the index.
460 unsafe { Some(self.data[offset].assume_init_ref()) }
461 } else {
462 None
463 }
464 }
465
466 /// Retrieves a mutable reference to an item at the given index.
467 ///
468 /// # Examples
469 ///
470 /// ```
471 /// use my_ecs::ds::ArrayDeque;
472 ///
473 /// let mut arr = ArrayDeque::<i32, 2>::new();
474 /// arr.push_back(0);
475 /// arr.push_front(1);
476 /// assert_eq!(arr.get_mut(1), Some(&mut 0));
477 /// ```
478 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
479 if index < self.len() {
480 let offset = self.offset(index);
481 // Safety: Checked the index.
482 unsafe { Some(self.data[offset].assume_init_mut()) }
483 } else {
484 None
485 }
486 }
487
488 /// Returns iterator traversing all items.
489 ///
490 /// # Examples
491 ///
492 /// ```
493 /// use my_ecs::ds::ArrayDeque;
494 ///
495 /// let mut arr = ArrayDeque::<i32, 2>::new();
496 /// arr.push_back(0);
497 /// arr.push_back(1);
498 /// for item in arr.iter() {
499 /// println!("{item}");
500 /// }
501 /// ```
502 pub fn iter(&self) -> Chain<slice::Iter<'_, T>, slice::Iter<'_, T>> {
503 let (a, b) = self.as_slices();
504 a.iter().chain(b.iter())
505 }
506
507 /// Returns mutable iterator traversing all items.
508 ///
509 /// # Examples
510 ///
511 /// ```
512 /// use my_ecs::ds::ArrayDeque;
513 ///
514 /// let mut arr = ArrayDeque::<i32, 2>::new();
515 /// arr.push_back(0);
516 /// arr.push_back(1);
517 /// for item in arr.iter_mut() {
518 /// *item += 1;
519 /// }
520 /// ```
521 pub fn iter_mut(&mut self) -> Chain<slice::IterMut<'_, T>, slice::IterMut<'_, T>> {
522 let (a, b) = self.as_mut_slices();
523 a.iter_mut().chain(b.iter_mut())
524 }
525
526 /// Returns front and back slices of `T` from the array.
527 ///
528 /// # Examples
529 ///
530 /// ```
531 /// use my_ecs::ds::ArrayDeque;
532 ///
533 /// let arr = ArrayDeque::<i32, 2>::new();
534 /// let slices: (&[i32], &[i32]) = arr.as_slices();
535 /// ```
536 pub fn as_slices(&self) -> (&[T], &[T]) {
537 debug_assert_eq!(
538 Layout::new::<[MaybeUninit<T>; N]>(),
539 Layout::new::<[T; N]>()
540 );
541
542 unsafe {
543 let data_a = self.data.as_ptr().add(self.head) as *const T;
544 let len_a = self.len().min(N - self.head);
545 let a = slice::from_raw_parts(data_a, len_a);
546
547 let b = if self.head + self.len() > N {
548 let data_b = self.data.as_ptr() as *const T;
549 let len_b = self.len() - len_a;
550 slice::from_raw_parts(data_b, len_b)
551 } else {
552 &[]
553 };
554
555 (a, b)
556 }
557 }
558
559 /// Returns front and back mutable slices of `T` from the array.
560 ///
561 /// # Examples
562 ///
563 /// ```
564 /// use my_ecs::ds::ArrayDeque;
565 ///
566 /// let mut arr = ArrayDeque::<i32, 2>::new();
567 /// let slices: (&mut [i32], &mut [i32]) = arr.as_mut_slices();
568 /// ```
569 pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
570 debug_assert_eq!(
571 Layout::new::<[MaybeUninit<T>; N]>(),
572 Layout::new::<[T; N]>()
573 );
574
575 unsafe {
576 let data_a = self.data.as_mut_ptr().add(self.head) as *mut T;
577 let len_a = self.len().min(N - self.head);
578 let a = slice::from_raw_parts_mut(data_a, len_a);
579
580 let b = if self.head + self.len() > N {
581 let data_b = self.data.as_mut_ptr() as *mut T;
582 let len_b = self.len() - len_a;
583 slice::from_raw_parts_mut(data_b, len_b)
584 } else {
585 &mut []
586 };
587
588 (a, b)
589 }
590 }
591
592 /// Removes all items in the array.
593 ///
594 /// # Examples
595 ///
596 /// ```
597 /// use my_ecs::ds::ArrayDeque;
598 ///
599 /// let mut arr = ArrayDeque::<i32, 2>::new();
600 /// arr.push_back(0);
601 /// arr.clear();
602 /// assert!(arr.is_empty());
603 /// ```
604 pub fn clear(&mut self) {
605 self.drop_in_place();
606 self.head = 0;
607 self.len = 0;
608 }
609
610 /// Appends a given item at the end of the array.
611 ///
612 /// # Examples
613 ///
614 /// ```
615 /// use my_ecs::ds::ArrayDeque;
616 ///
617 /// let mut arr = ArrayDeque::<i32, 2>::new();
618 /// arr.push_back(0);
619 /// ```
620 pub fn push_back(&mut self, value: T) -> bool {
621 if !self.is_full() {
622 let tail = self.offset(self.len());
623 self.data[tail].write(value);
624 self.len += 1;
625 true
626 } else {
627 false
628 }
629 }
630
631 /// Appends a given item at the beginning of the array.
632 ///
633 /// # Examples
634 ///
635 /// ```
636 /// use my_ecs::ds::ArrayDeque;
637 ///
638 /// let mut arr = ArrayDeque::<i32, 2>::new();
639 /// arr.push_front(0);
640 /// ```
641 pub fn push_front(&mut self, value: T) -> bool {
642 if !self.is_full() {
643 self.head = self.offset(N - 1);
644 self.data[self.head].write(value);
645 self.len += 1;
646 true
647 } else {
648 false
649 }
650 }
651
652 /// Takes out an item from the end of the array.
653 ///
654 /// # Examples
655 ///
656 /// ```
657 /// use my_ecs::ds::ArrayDeque;
658 ///
659 /// let mut arr = ArrayDeque::<i32, 2>::new();
660 /// arr.push_back(0);
661 /// arr.push_back(1);
662 /// assert_eq!(arr.pop_back(), Some(1));
663 /// assert_eq!(arr.pop_back(), Some(0));
664 /// ```
665 pub fn pop_back(&mut self) -> Option<T> {
666 if !self.is_empty() {
667 self.len -= 1;
668 let tail = self.offset(self.len());
669 // Safety: It's not empty, so data[tail] must have been initialized.
670 unsafe { Some(self.data[tail].assume_init_read()) }
671 } else {
672 None
673 }
674 }
675
676 /// Takes out an item from the beginning of the array.
677 ///
678 /// # Examples
679 ///
680 /// ```
681 /// use my_ecs::ds::ArrayDeque;
682 ///
683 /// let mut arr = ArrayDeque::<i32, 2>::new();
684 /// arr.push_back(0);
685 /// arr.push_back(1);
686 /// assert_eq!(arr.pop_front(), Some(0));
687 /// assert_eq!(arr.pop_front(), Some(1));
688 /// ```
689 pub fn pop_front(&mut self) -> Option<T> {
690 if !self.is_empty() {
691 // Safety: It's not empty, so data[head] must have been initialized.
692 let value = unsafe { self.data[self.head].assume_init_read() };
693 self.head = (self.head + 1) % N;
694 self.len -= 1;
695 Some(value)
696 } else {
697 None
698 }
699 }
700
701 /// Returns shared reference to the last item.
702 ///
703 /// # Examples
704 ///
705 /// ```
706 /// use my_ecs::ds::ArrayDeque;
707 ///
708 /// let mut arr = ArrayDeque::<i32, 2>::new();
709 /// arr.push_back(0);
710 /// arr.push_back(1);
711 /// assert_eq!(arr.back(), Some(&1));
712 /// ```
713 pub fn back(&self) -> Option<&T> {
714 if !self.is_empty() {
715 let index = (self.head + self.len - 1) % N;
716 // Safety: It's not empty, so data[index] must have been initialized.
717 unsafe { Some(self.data[index].assume_init_ref()) }
718 } else {
719 None
720 }
721 }
722
723 /// Returns shared reference to the first item.
724 ///
725 /// # Examples
726 ///
727 /// ```
728 /// use my_ecs::ds::ArrayDeque;
729 ///
730 /// let mut arr = ArrayDeque::<i32, 2>::new();
731 /// arr.push_back(0);
732 /// arr.push_back(1);
733 /// assert_eq!(arr.front(), Some(&0));
734 /// ```
735 pub fn front(&self) -> Option<&T> {
736 if !self.is_empty() {
737 // Safety: It's not empty, so data[head] must have been initialized.
738 unsafe { Some(self.data[self.head].assume_init_ref()) }
739 } else {
740 None
741 }
742 }
743
744 const fn offset(&self, index: usize) -> usize {
745 (self.head + index) % N
746 }
747
748 fn drop_in_place(&mut self) {
749 let (a, b) = self.as_mut_slices();
750
751 unsafe {
752 ptr::drop_in_place(a as *mut _);
753 ptr::drop_in_place(b as *mut _);
754 }
755 }
756}
757
758impl<T, const N: usize> Default for ArrayDeque<T, N> {
759 fn default() -> Self {
760 Self::new()
761 }
762}
763
764impl<T, const N: usize> Drop for ArrayDeque<T, N> {
765 fn drop(&mut self) {
766 if mem::needs_drop::<T>() {
767 self.drop_in_place();
768 }
769 }
770}
771
772impl<T, const N: usize> Index<usize> for ArrayDeque<T, N> {
773 type Output = T;
774
775 fn index(&self, index: usize) -> &Self::Output {
776 self.get(index).expect("Out of bounds access")
777 }
778}
779
780impl<T, const N: usize> IndexMut<usize> for ArrayDeque<T, N> {
781 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
782 self.get_mut(index).expect("Out of bounds access")
783 }
784}
785
786#[cfg(test)]
787mod tests {
788 use super::*;
789
790 #[test]
791 fn test_arraydeque_new() {
792 let arr: ArrayDeque<i32, 3> = ArrayDeque::new();
793 assert_eq!(arr.len(), 0);
794 assert!(arr.is_empty());
795 assert!(!arr.is_full());
796 }
797
798 #[test]
799 fn test_arraydeque_push_back() {
800 let mut arr: ArrayDeque<i32, 3> = ArrayDeque::new();
801 assert!(arr.push_back(1));
802 assert!(arr.push_back(2));
803 assert!(arr.push_back(3));
804 assert!(!arr.push_back(4)); // ArrayDeque is full
805 assert_eq!(arr.len(), 3);
806 assert!(arr.is_full());
807 }
808
809 #[test]
810 fn test_arraydeque_push_front() {
811 let mut arr: ArrayDeque<i32, 3> = ArrayDeque::new();
812 assert!(arr.push_front(1));
813 assert!(arr.push_front(2));
814 assert!(arr.push_front(3));
815 assert!(!arr.push_front(4)); // ArrayDeque is full
816 assert_eq!(arr.len(), 3);
817 assert!(arr.is_full());
818 }
819
820 #[test]
821 fn test_arraydeque_pop_back() {
822 let mut arr: ArrayDeque<i32, 3> = ArrayDeque::new();
823 arr.push_back(1);
824 arr.push_back(2);
825 arr.push_back(3);
826 assert_eq!(arr.pop_back(), Some(3));
827 assert_eq!(arr.pop_back(), Some(2));
828 assert_eq!(arr.pop_back(), Some(1));
829 assert_eq!(arr.pop_back(), None);
830 assert!(arr.is_empty());
831 }
832
833 #[test]
834 fn test_arraydeque_pop_front() {
835 let mut arr: ArrayDeque<i32, 3> = ArrayDeque::new();
836 arr.push_back(1);
837 arr.push_back(2);
838 arr.push_back(3);
839 assert_eq!(arr.pop_front(), Some(1));
840 assert_eq!(arr.pop_front(), Some(2));
841 assert_eq!(arr.pop_front(), Some(3));
842 assert_eq!(arr.pop_front(), None);
843 assert!(arr.is_empty());
844 }
845
846 #[test]
847 fn test_arraydeque_peek() {
848 let mut arr: ArrayDeque<i32, 3> = ArrayDeque::new();
849 assert_eq!(arr.back(), None);
850 assert_eq!(arr.front(), None);
851 arr.push_back(1);
852 arr.push_back(2);
853 arr.push_back(3);
854 assert_eq!(arr.front(), Some(&1));
855 assert_eq!(arr.pop_front(), Some(1));
856 assert_eq!(arr.back(), Some(&3));
857 assert_eq!(arr.pop_back(), Some(3));
858 assert_eq!(arr.back(), Some(&2));
859 assert_eq!(arr.pop_back(), Some(2));
860 assert!(arr.is_empty());
861 }
862
863 #[test]
864 fn test_arraydeque_mixed_operations() {
865 let mut arr: ArrayDeque<i32, 3> = ArrayDeque::new();
866 arr.push_back(1);
867 arr.push_front(2);
868 arr.push_back(3);
869 assert_eq!(arr.len(), 3);
870 assert_eq!(arr.pop_front(), Some(2));
871 assert_eq!(arr.pop_back(), Some(3));
872 assert_eq!(arr.pop_back(), Some(1));
873 assert!(arr.is_empty());
874 }
875
876 #[test]
877 fn test_arraydeque_wrap_around() {
878 let mut arr: ArrayDeque<i32, 3> = ArrayDeque::new();
879 for i in 0..30 {
880 if arr.is_full() {
881 assert_eq!(arr.pop_front(), Some(i - 3));
882 }
883 arr.push_back(i);
884 }
885 assert_eq!(arr.pop_front(), Some(30 - 3));
886 assert_eq!(arr.pop_front(), Some(30 - 2));
887 assert_eq!(arr.pop_front(), Some(30 - 1));
888 assert!(arr.is_empty());
889 }
890
891 #[test]
892 fn test_arraydeque_drop() {
893 use std::{cell::RefCell, rc::Rc};
894
895 let counter = Rc::new(RefCell::new(0));
896
897 struct Droppable(Rc<RefCell<i32>>);
898
899 impl Drop for Droppable {
900 fn drop(&mut self) {
901 *self.0.borrow_mut() += 1;
902 }
903 }
904
905 {
906 let mut arr: ArrayDeque<Droppable, 3> = ArrayDeque::new();
907 arr.push_back(Droppable(Rc::clone(&counter)));
908 arr.push_back(Droppable(Rc::clone(&counter)));
909 arr.push_back(Droppable(Rc::clone(&counter)));
910 } // arr goes out of scope here
911
912 assert_eq!(*counter.borrow(), 3);
913
914 // wrap around
915 *counter.borrow_mut() = 0;
916 {
917 let mut arr: ArrayDeque<Droppable, 3> = ArrayDeque::new();
918 arr.push_back(Droppable(Rc::clone(&counter)));
919 arr.push_back(Droppable(Rc::clone(&counter)));
920 arr.push_back(Droppable(Rc::clone(&counter)));
921 arr.pop_front();
922 arr.pop_front();
923 arr.push_back(Droppable(Rc::clone(&counter)));
924 } // arr goes out of scope here
925
926 assert_eq!(*counter.borrow(), 4);
927 }
928}