use core::mem::MaybeUninit;
#[derive(Debug)]
pub struct ArrayVec<T, const N: usize> {
data: [MaybeUninit<T>; N],
len: usize,
}
#[derive(Debug, Clone)]
pub enum ArrayVecError {
CapacityOverflow,
}
impl core::fmt::Display for ArrayVecError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::CapacityOverflow => f.write_str("capacity overflow"),
}
}
}
impl core::error::Error for ArrayVecError {}
impl<T, const N: usize> ArrayVec<T, N> {
pub const fn new() -> Self {
Self {
data: [const { MaybeUninit::uninit() }; N],
len: 0,
}
}
pub fn try_push(&mut self, value: T) -> Result<(), ArrayVecError> {
if self.len == N {
return Err(ArrayVecError::CapacityOverflow);
}
self.data[self.len].write(value);
self.len += 1;
Ok(())
}
pub fn push(&mut self, value: T) {
self.try_push(value).expect("ArrayVec: ran out of capacity");
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn as_slice(&self) -> &[T] {
unsafe { core::slice::from_raw_parts(self.data.as_ptr() as *const T, self.len) }
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
unsafe { core::slice::from_raw_parts_mut(self.data.as_mut_ptr() as *mut T, self.len) }
}
pub fn iter(&self) -> core::slice::Iter<'_, T> {
self.as_slice().iter()
}
pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> {
self.as_mut_slice().iter_mut()
}
pub fn reverse(&mut self) {
let len = self.len;
for i in 0..len / 2 {
let j = len - i - 1;
self.data.swap(i, j);
}
}
pub fn as_ptr(&self) -> *const T {
self.data.as_ptr() as *const T
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.data.as_mut_ptr() as *mut T
}
}
impl<T, const U: usize> ArrayVec<T, U>
where
T: Copy + PartialEq,
{
pub fn contains(&self, value: &T) -> bool {
self.iter().any(|x| x == value)
}
}
impl<T, const U: usize> ArrayVec<T, U>
where
T: Copy + Ord,
{
pub fn sort_unstable(&mut self) {
self.as_mut_slice().sort_unstable();
}
}
impl<T, const N: usize> core::ops::Index<usize> for ArrayVec<T, N>
where
T: Copy,
{
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
unsafe { self.data[index].assume_init_ref() }
}
}
impl<T, const N: usize> core::ops::IndexMut<usize> for ArrayVec<T, N>
where
T: Copy,
{
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
unsafe { self.data[index].assume_init_mut() }
}
}