1pub mod iter;
2
3use std::fmt::{Debug, Display};
4use std::ops::{Add, Index, IndexMut};
5use crate::iter::CircularArrayIter;
6
7#[derive(Debug)]
9pub struct CircularArray<const N: usize, T> {
10 arr: [T;N],
11 start: usize,
12 len: usize,
13}
14
15impl<const N: usize, T> CircularArray<N, T> where T: Copy + Default + Debug + Display {
16 pub fn new() -> Self {
17 Self {
18 arr: [T::default(); N],
19 start: 0,
20 len: 0,
21 }
22 }
23
24 pub fn push(&mut self, item: T) {
40 if self.len >= N {
41 self.arr[self.start] = item;
42 } else {
43 self.arr[self.len] = item;
44 }
45 self.start = (self.start + 1) % N;
46 self.len += 1;
47 }
48
49 pub fn to_array(&self) -> [T;N] {
64 unsafe {
65 let mut arr = [T::default(); N];
66
67 let src_ptr = self.arr.as_ptr();
68 let dest_ptr = arr.as_mut_ptr();
69
70 if self.len >= N && self.start > 0 {
71 std::ptr::copy_nonoverlapping(src_ptr.add(self.start), dest_ptr, N - self.start);
72 std::ptr::copy_nonoverlapping(src_ptr, dest_ptr.add(N - self.start), N - self.start);
73 } else {
74 std::ptr::copy_nonoverlapping(src_ptr, dest_ptr, N);
75 }
76 arr
77 }
78 }
79
80 pub fn iter(&self) -> CircularArrayIter<N, T> {
94 CircularArrayIter::new(&self)
95 }
96
97
98 pub fn last(&self) -> Option<&T> {
114 if self.len >= N {
115 Some(&self[N-1])
116 } else if self.len > 0 {
117 Some(&self[self.len -1])
118 } else {
119 None
120 }
121 }
122
123 pub fn len(&self) -> usize {
124 self.len
125 }
126}
127
128
129impl<T, const N: usize> Index<usize> for CircularArray<N, T> where [T]: Index<usize>, T: Default + Copy
130{
131 type Output = <[T] as Index<usize>>::Output;
132
133 #[inline]
134 fn index(&self, index: usize) -> &Self::Output {
135 if self.len >= N {
136 &self.arr[(self.start + index) % N]
137 } else {
138 &self.arr[index]
139 }
140 }
141}
142
143impl<T, const N: usize> IndexMut<usize> for CircularArray<N, T>
144 where [T]: Index<usize>,
145 T: Default + Copy, usize: Add<usize> {
146
147 #[inline]
148 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
149 if self.len >= N {
150 &mut self.arr[(self.start + index) % N]
151 } else {
152 &mut self.arr[index]
153 }
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160
161 #[test]
162 fn test_push() {
163 let mut arr = CircularArray::<3, u32>::new();
164 arr.push(1);
165 arr.push(2);
166 arr.push(3);
167 assert_eq!(arr.arr, [1, 2, 3]);
168 arr.push(4);
169 assert_eq!(arr.arr, [4, 2, 3]);
170 }
171
172 #[test]
173 #[allow(non_snake_case)]
174 fn test_Index_and_IndexMut() {
175 let mut arr = CircularArray::<3, u32>::new();
176 arr.push(0);
177 arr.push(0);
178 arr.push(0);
179 arr.push(0);
180 arr.push(0);
181 arr[0] = 1;
182 arr[1] = 2;
183 arr[2] = 3;
184 assert_eq!(arr[0], 1);
185 assert_eq!(arr[1], 2);
186 assert_eq!(arr[2], 3);
187 }
188
189 #[test]
190 fn test_to_array() {
191 let mut arr = CircularArray::<3, u32>::new();
192 arr.push(1);
193 arr.push(2);
194 arr.push(3);
195 assert_eq!(arr.to_array(), [1, 2, 3]);
196 arr.push(4);
197 assert_eq!(arr.to_array(), [2, 3, 4]);
198 }
199
200 #[test]
201 fn test_last() {
202 let mut arr = CircularArray::<3, u32>::new();
203 assert_eq!(arr.last(), None);
204 arr.push(1);
205 assert_eq!(arr.last(), Some(1).as_ref());
206 arr.push(2);
207 arr.push(3);
208 arr.push(4);
209 assert_eq!(arr.last(), Some(4).as_ref());
210 }
211
212 #[test]
213 fn test_len() {
214 let mut arr = CircularArray::<3, u32>::new();
215 assert_eq!(arr.len(), 0);
216 arr.push(1);
217 assert_eq!(arr.len(), 1);
218 arr.push(2);
219 arr.push(3);
220 arr.push(4);
221 assert_eq!(arr.len(), 4);
222 }
223}
224