use core::fmt::{Debug, Formatter}; pub fn fill_with T>(slice: &mut [T], mut func: F) { slice.iter_mut().enumerate().for_each(|(i,v)|*v = func(i)) } pub struct FixedVec { length: usize, buffer: [core::mem::MaybeUninit;MAX_LEN], } impl FixedVec { 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 { if self.length == 0 { return None } self.length -= 1; Some(unsafe { self.buffer[self.length].assume_init_read() }) } pub fn extend>(&mut self, mut iter: Iter) -> Result { 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 Debug for FixedVec { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { Debug::fmt(self.as_slice(), f) } } impl Drop for FixedVec { fn drop(&mut self) { for e in &mut self.buffer[..self.length] { unsafe { e.assume_init_drop() } } } } impl core::fmt::Write for FixedVec { fn write_str(&mut self, s: &str) -> core::fmt::Result { _=self.extend(s.as_bytes().iter().cloned()); Ok(()) } }