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}