std/backtrace/src/symbolize/gimli/
lru.rsuse core::mem::{self, MaybeUninit};
use core::ptr;
pub(crate) struct Lru<T, const N: usize> {
len: usize,
arr: [MaybeUninit<T>; N],
}
impl<T, const N: usize> Default for Lru<T, N> {
fn default() -> Self {
Lru {
len: 0,
arr: [const { MaybeUninit::uninit() }; N],
}
}
}
impl<T, const N: usize> Lru<T, N> {
#[inline]
pub fn clear(&mut self) {
let len = self.len;
self.len = 0;
unsafe { ptr::drop_in_place(ptr::addr_of_mut!(self.arr[0..len]) as *mut [T]) }
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.arr[0..self.len]
.iter()
.map(|init| unsafe { init.assume_init_ref() })
}
#[inline]
pub fn push_front(&mut self, value: T) -> Option<&mut T> {
if N == 0 {
return None;
} else if self.len == N {
self.len = N - 1;
unsafe { ptr::drop_in_place(self.arr.as_mut_ptr().cast::<T>().add(N - 1)) };
};
let len_to_init = self.len + 1;
let mut last = MaybeUninit::new(value);
for elem in self.arr[0..len_to_init].iter_mut() {
last = mem::replace(elem, last);
}
self.len = len_to_init;
self.arr
.first_mut()
.map(|elem| unsafe { elem.assume_init_mut() })
}
#[inline]
pub fn move_to_front(&mut self, idx: usize) -> Option<&mut T> {
let elem = self.arr[0..self.len].get_mut(idx)?;
let mut last = mem::replace(elem, MaybeUninit::uninit());
for elem in self.arr[0..=idx].iter_mut() {
last = mem::replace(elem, last);
}
self.arr
.first_mut()
.map(|elem| unsafe { elem.assume_init_mut() })
}
}