1use core::borrow::Borrow;
4use core::convert::AsRef;
5use core::mem::MaybeUninit;
6use core::ops::{Deref, DerefMut};
7use core::{ptr, slice};
8
9pub struct History<T, const N: usize> {
10 is_full: bool,
11 last: usize,
12 logs: MaybeUninit<[T; N]>,
13}
14impl<T, const N: usize> History<T, N> {
15 const CAPACITY: usize = N;
16 pub const fn new() -> Self {
17 History {
18 is_full: false,
19 last: 0,
20 logs: MaybeUninit::uninit(),
21 }
22 }
23 fn as_ptr(&self) -> *mut T {
24 self.logs.as_ptr() as *mut T
25 }
26 pub fn insert(&mut self, value: T) {
28 let last = self.last;
29 if self.is_full {
30 unsafe { slice::from_raw_parts_mut(self.as_ptr(), Self::CAPACITY)[last] = value };
31 } else {
32 unsafe { ptr::write(self.as_ptr().add(last), value) };
33 };
34 if last == Self::CAPACITY - 1 {
35 self.last = 0;
36 self.is_full = true;
37 } else {
38 self.last = last + 1;
39 }
40 }
41}
42impl<T, const N: usize> Deref for History<T, N> {
43 type Target = [T];
44
45 fn deref(&self) -> &[T] {
46 if self.is_full {
47 unsafe { slice::from_raw_parts(self.as_ptr(), Self::CAPACITY) }
48 } else {
49 unsafe { slice::from_raw_parts(self.as_ptr(), self.last) }
50 }
51 }
52}
53impl<T, const N: usize> DerefMut for History<T, N> {
54 fn deref_mut(&mut self) -> &mut [T] {
55 if self.is_full {
56 unsafe { slice::from_raw_parts_mut(self.as_ptr(), Self::CAPACITY) }
57 } else {
58 unsafe { slice::from_raw_parts_mut(self.as_ptr(), self.last) }
59 }
60 }
61}
62impl<T, const N: usize> AsRef<[T]> for History<T, N> {
63 fn as_ref(&self) -> &[T] {
64 self
65 }
66}
67impl<T, const N: usize> Borrow<[T]> for History<T, N> {
68 fn borrow(&self) -> &[T] {
69 &self[..]
70 }
71}
72impl<T, const N: usize> Drop for History<T, N> {
73 fn drop(&mut self) {
74 unsafe { ptr::drop_in_place(self.deref_mut()) };
75 }
76}