1use crate::CircularBuffer;
7use crate::Inner;
8use crate::Iter;
9use crate::IterMut;
10use core::borrow::Borrow;
11use core::borrow::BorrowMut;
12use core::mem;
13use core::mem::MaybeUninit;
14use core::ops::Deref;
15use core::ops::DerefMut;
16use core::ops::Index;
17use core::ops::IndexMut;
18use core::ptr;
19
20#[cfg(all(not(feature = "std"), feature = "alloc"))]
21use alloc::boxed::Box;
22
23pub use crate::iter::fixed::IntoIter;
24
25#[repr(transparent)]
37pub struct FixedCircularBuffer<T, const N: usize> {
38 inner: Inner<[MaybeUninit<T>; N]>,
39}
40
41impl<T, const N: usize> FixedCircularBuffer<T, N> {
42 #[inline]
54 #[must_use]
55 pub const fn new() -> Self {
56 Self {
57 inner: Inner {
58 size: 0,
59 start: 0,
60 items: [const { MaybeUninit::uninit() }; N],
61 },
62 }
63 }
64
65 #[must_use]
75 #[cfg(feature = "alloc")]
76 pub fn boxed() -> Box<Self> {
77 let mut uninit: Box<MaybeUninit<Self>> = Box::new_uninit();
78 let ptr = uninit.as_mut_ptr();
79
80 unsafe {
83 core::ptr::addr_of_mut!((*ptr).inner.size).write(0);
84 core::ptr::addr_of_mut!((*ptr).inner.start).write(0);
85 }
86
87 unsafe { uninit.assume_init() }
90 }
91
92 #[inline]
94 #[must_use]
95 pub const fn as_circular_buffer(&self) -> &CircularBuffer<T> {
96 let inner_unsized: &Inner<[MaybeUninit<T>]> = &self.inner;
99 unsafe { mem::transmute(inner_unsized) }
104 }
105
106 #[inline]
108 #[must_use]
109 pub const fn as_mut_circular_buffer(&mut self) -> &mut CircularBuffer<T> {
110 let inner_unsized: &mut Inner<[MaybeUninit<T>]> = &mut self.inner;
113 unsafe { mem::transmute(inner_unsized) }
118 }
119}
120
121impl<T, const N: usize> Default for FixedCircularBuffer<T, N> {
122 #[inline]
123 fn default() -> Self {
124 Self::new()
125 }
126}
127
128impl<const N: usize, const M: usize, T> From<[T; M]> for FixedCircularBuffer<T, N> {
129 fn from(mut arr: [T; M]) -> Self {
130 let size = if N >= M { M } else { N };
131 let mut elems = [const { MaybeUninit::uninit() }; N];
132 let (discard, copy) = arr.split_at_mut(M - size);
133
134 debug_assert_eq!(copy.len(), size);
135
136 let elems_ptr = elems.as_mut_ptr();
137 let discard_ptr = discard as *mut [T];
138 let copy_ptr = copy.as_ptr() as *const MaybeUninit<T>;
139
140 unsafe {
145 copy_ptr.copy_to_nonoverlapping(elems_ptr, size);
146 }
147
148 mem::forget(arr);
150
151 unsafe {
157 ptr::drop_in_place(discard_ptr);
158 }
159
160 Self {
161 inner: Inner {
162 size,
163 start: 0,
164 items: elems,
165 },
166 }
167 }
168}
169
170impl<T, const N: usize> FromIterator<T> for FixedCircularBuffer<T, N> {
171 fn from_iter<I>(iter: I) -> Self
172 where
173 I: IntoIterator<Item = T>,
174 {
175 let mut buf = Self::new();
177 iter.into_iter().for_each(|item| {
178 buf.push_back(item);
179 });
180 buf
181 }
182}
183
184impl<T, const N: usize> Deref for FixedCircularBuffer<T, N> {
185 type Target = CircularBuffer<T>;
186
187 #[inline]
188 fn deref(&self) -> &Self::Target {
189 self.as_circular_buffer()
190 }
191}
192
193impl<T, const N: usize> DerefMut for FixedCircularBuffer<T, N> {
194 #[inline]
195 fn deref_mut(&mut self) -> &mut Self::Target {
196 self.as_mut_circular_buffer()
197 }
198}
199
200impl<T, const N: usize> Borrow<CircularBuffer<T>> for FixedCircularBuffer<T, N> {
201 #[inline]
202 fn borrow(&self) -> &CircularBuffer<T> {
203 self.as_circular_buffer()
204 }
205}
206
207impl<T, const N: usize> BorrowMut<CircularBuffer<T>> for FixedCircularBuffer<T, N> {
208 #[inline]
209 fn borrow_mut(&mut self) -> &mut CircularBuffer<T> {
210 self.as_mut_circular_buffer()
211 }
212}
213
214impl<T, const N: usize> AsRef<CircularBuffer<T>> for FixedCircularBuffer<T, N> {
215 #[inline]
216 fn as_ref(&self) -> &CircularBuffer<T> {
217 self.as_circular_buffer()
218 }
219}
220
221impl<T, const N: usize> AsMut<CircularBuffer<T>> for FixedCircularBuffer<T, N> {
222 #[inline]
223 fn as_mut(&mut self) -> &mut CircularBuffer<T> {
224 self.as_mut_circular_buffer()
225 }
226}
227
228impl<T, const N: usize> Extend<T> for FixedCircularBuffer<T, N> {
229 fn extend<I>(&mut self, iter: I)
230 where
231 I: IntoIterator<Item = T>,
232 {
233 self.deref_mut().extend(iter);
234 }
235}
236
237impl<'a, T, const N: usize> Extend<&'a T> for FixedCircularBuffer<T, N>
238where
239 T: Copy,
240{
241 fn extend<I>(&mut self, iter: I)
242 where
243 I: IntoIterator<Item = &'a T>,
244 {
245 self.deref_mut().extend(iter);
246 }
247}
248
249impl<T, const N: usize> Index<usize> for FixedCircularBuffer<T, N> {
250 type Output = T;
251
252 #[inline]
253 fn index(&self, index: usize) -> &Self::Output {
254 self.deref().index(index)
255 }
256}
257
258impl<T, const N: usize> IndexMut<usize> for FixedCircularBuffer<T, N> {
259 #[inline]
260 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
261 self.deref_mut().index_mut(index)
262 }
263}
264
265impl<T, const N: usize> IntoIterator for FixedCircularBuffer<T, N> {
266 type Item = T;
267 type IntoIter = IntoIter<T, N>;
268
269 #[inline]
270 fn into_iter(self) -> Self::IntoIter {
271 IntoIter::new(self)
272 }
273}
274
275impl<'a, T, const N: usize> IntoIterator for &'a FixedCircularBuffer<T, N> {
276 type Item = &'a T;
277 type IntoIter = Iter<'a, T>;
278
279 #[inline]
280 fn into_iter(self) -> Self::IntoIter {
281 Iter::new(self)
282 }
283}
284
285impl<'a, T, const N: usize> IntoIterator for &'a mut FixedCircularBuffer<T, N> {
286 type Item = &'a mut T;
287 type IntoIter = IterMut<'a, T>;
288
289 #[inline]
290 fn into_iter(self) -> Self::IntoIter {
291 IterMut::new(self)
292 }
293}
294
295impl<T, const N: usize> Clone for FixedCircularBuffer<T, N>
296where
297 T: Clone,
298{
299 fn clone(&self) -> Self {
300 let (front, back) = self.as_slices();
301 let mut buf = Self::new();
302 buf.extend_from_slice(front);
303 buf.extend_from_slice(back);
304 buf
305 }
306
307 fn clone_from(&mut self, other: &Self) {
308 let (front, back) = other.as_slices();
309 self.clear();
310 self.extend_from_slice(front);
311 self.extend_from_slice(back);
312 }
313}
314
315impl<T, const N: usize> Drop for FixedCircularBuffer<T, N> {
316 #[inline]
317 fn drop(&mut self) {
318 self.clear();
320 }
321}