80 lines
2.2 KiB
Rust
80 lines
2.2 KiB
Rust
use core::fmt::{Debug, Formatter};
|
|
|
|
pub fn fill_with<T, F: FnMut(usize) -> T>(slice: &mut [T], mut func: F) {
|
|
slice.iter_mut().enumerate().for_each(|(i,v)|*v = func(i))
|
|
}
|
|
|
|
|
|
pub struct FixedVec<const MAX_LEN: usize, T> {
|
|
length: usize,
|
|
buffer: [core::mem::MaybeUninit<T>;MAX_LEN],
|
|
}
|
|
|
|
impl<const MAX_LEN: usize, T: Sized> FixedVec<MAX_LEN, T> {
|
|
|
|
pub fn new() -> Self {
|
|
unsafe { core::mem::zeroed() }
|
|
}
|
|
|
|
pub fn push(&mut self, value: T) -> Option<()> {
|
|
if self.length >= MAX_LEN { return None }
|
|
unsafe { *self.buffer[self.length].as_mut_ptr() = value };
|
|
self.length += 1;
|
|
Some(())
|
|
}
|
|
|
|
pub fn pop(&mut self) -> Option<T> {
|
|
if self.length == 0 { return None }
|
|
self.length -= 1;
|
|
Some(unsafe { self.buffer[self.length].assume_init_read() })
|
|
}
|
|
|
|
pub fn extend<Iter: Iterator<Item=T>>(&mut self, mut iter: Iter) -> Result<usize, usize> {
|
|
let mut count = 0;
|
|
loop {
|
|
if self.length == MAX_LEN {
|
|
return Err(count);
|
|
}
|
|
match iter.next() {
|
|
None => return Ok(count),
|
|
Some(value) => {
|
|
unsafe { *self.buffer[self.length].as_mut_ptr() = value };
|
|
self.length += 1;
|
|
count += 1;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
pub fn as_slice(&self) -> &[T] {
|
|
// length can't be larger than MaxLen, use unsafe to dodge the panic
|
|
unsafe { core::slice::from_raw_parts(self.buffer.as_ptr() as *const T, self.length) }
|
|
}
|
|
|
|
pub fn clear(&mut self) {
|
|
self.length = 0;
|
|
}
|
|
|
|
}
|
|
|
|
impl<const MAX_LEN: usize, T: Debug> Debug for FixedVec<MAX_LEN, T> {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
|
Debug::fmt(self.as_slice(), f)
|
|
}
|
|
}
|
|
|
|
impl<const MAX_LEN: usize, T> Drop for FixedVec<MAX_LEN, T> {
|
|
fn drop(&mut self) {
|
|
for e in &mut self.buffer[..self.length] {
|
|
unsafe { e.assume_init_drop() }
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<const MAX_LEN: usize> core::fmt::Write for FixedVec<MAX_LEN, u8> {
|
|
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
|
_=self.extend(s.as_bytes().iter().cloned());
|
|
Ok(())
|
|
}
|
|
} |