fixed_queue/
history.rs

1//! 历史记录
2
3use 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    /// 添加记录
27    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}