use std::mem::{transmute, MaybeUninit}; use std::ops::{Deref, DerefMut}; #[derive(Debug)] pub struct ArrayVec { items: [MaybeUninit; CAPACITY], len: usize, } impl ArrayVec { pub fn new() -> Self { Self::default() } #[inline] #[must_use] pub fn len(&self) -> usize { self.len } pub fn push(&mut self, item: Item) { assert!(self.len < CAPACITY); self.items[self.len].write(item); self.len += 1; } pub fn insert(&mut self, index: usize, item: Item) { assert!(index <= self.len); assert!(self.len < CAPACITY); if index == self.len { self.push(item); return; } unsafe { std::ptr::copy( &self.items[index], &mut self.items[index + 1], self.len - index, ); } self.items[index].write(item); self.len += 1; } } impl Extend for ArrayVec { fn extend>(&mut self, iter: IntoIter) { for item in iter { self.push(item); } } } impl AsRef<[Item]> for ArrayVec { fn as_ref(&self) -> &[Item] { unsafe { transmute::<&[MaybeUninit], &[Item]>(&self.items[..self.len]) } } } impl AsMut<[Item]> for ArrayVec { fn as_mut(&mut self) -> &mut [Item] { unsafe { transmute::<&mut [MaybeUninit], &mut [Item]>( &mut self.items[..self.len], ) } } } impl Deref for ArrayVec { type Target = [Item]; fn deref(&self) -> &Self::Target { self.as_ref() } } impl DerefMut for ArrayVec { fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut() } } impl Default for ArrayVec { fn default() -> Self { Self { items: [const { MaybeUninit::uninit() }; CAPACITY], len: 0, } } }