use core::iter::ExactSizeIterator;
use core::iter::FusedIterator;
use core::mem::MaybeUninit;
pub struct ArrayVec<T: Copy, const N: usize> {
len: usize,
array: [MaybeUninit<T>; N],
}
impl<T: Copy, const N: usize> ArrayVec<T, N> {
#[inline]
pub fn new() -> Self {
Self {
len: 0,
array: [const { MaybeUninit::uninit() }; N],
}
}
#[inline]
pub fn push(&mut self, value: T) {
self.array.get_mut(self.len).unwrap().write(value);
self.len += 1;
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn as_slice(&self) -> &[T] {
let t = self.array.get(0..self.len).unwrap();
unsafe { core::mem::transmute::<&[MaybeUninit<T>], &[T]>(t) }
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
let t = self.array.get_mut(0..self.len).unwrap();
unsafe { core::mem::transmute::<&mut [MaybeUninit<T>], &mut [T]>(t) }
}
#[inline]
pub fn iter<'l>(&'l self) -> ArrayVecIter<'l, T, N> {
ArrayVecIter {
inner: self.as_slice().iter().copied(),
}
}
}
impl<T: Copy, const N: usize> Clone for ArrayVec<T, N> {
fn clone(&self) -> Self {
Self {
len: self.len,
array: self.array,
}
}
}
impl<T: Copy, const N: usize> core::fmt::Debug for ArrayVec<T, N>
where
T: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
f.debug_list().entries(self.as_slice()).finish()
}
}
#[derive(Clone)]
pub struct ArrayVecIntoIter<T: Copy, const N: usize> {
index: usize,
array: ArrayVec<T, N>,
}
impl<T: Copy, const N: usize> IntoIterator for ArrayVec<T, N> {
type Item = T;
type IntoIter = ArrayVecIntoIter<T, N>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
ArrayVecIntoIter {
index: 0,
array: self,
}
}
}
impl<T: Copy, const N: usize> ArrayVecIntoIter<T, N> {
fn as_slice(&self) -> &[T] {
&self.array.as_slice()[self.index..]
}
}
impl<T: Copy, const N: usize> Iterator for ArrayVecIntoIter<T, N> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<T> {
let res = self.array.as_slice().get(self.index)?;
self.index += 1;
Some(*res)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
#[inline]
fn count(self) -> usize
where
Self: Sized,
{
self.len()
}
#[inline]
fn last(self) -> Option<T>
where
Self: Sized,
{
self.as_slice().last().copied()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<T> {
match self.array.as_slice().get(n) {
Some(res) => {
self.index += n + 1;
Some(*res)
}
None => {
self.index += self.len();
None
}
}
}
#[inline]
fn for_each<F>(self, f: F)
where
Self: Sized,
F: FnMut(T),
{
self.as_slice().iter().copied().for_each(f)
}
#[inline]
fn fold<B, F>(self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, T) -> B,
{
self.as_slice().iter().copied().fold(init, f)
}
}
impl<T: Copy, const N: usize> FusedIterator for ArrayVecIntoIter<T, N> {}
impl<T: Copy, const N: usize> ExactSizeIterator for ArrayVecIntoIter<T, N> {
#[inline]
fn len(&self) -> usize {
self.as_slice().len()
}
}
impl<T: Copy, const N: usize> core::fmt::Debug for ArrayVecIntoIter<T, N>
where
T: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
f.debug_list().entries(self.as_slice()).finish()
}
}
pub struct ArrayVecIter<'l, T: Copy, const N: usize> {
inner: core::iter::Copied<core::slice::Iter<'l, T>>,
}
impl<'l, T: Copy, const N: usize> IntoIterator for &'l ArrayVec<T, N> {
type Item = T;
type IntoIter = ArrayVecIter<'l, T, N>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
ArrayVecIter {
inner: self.as_slice().iter().copied(),
}
}
}
impl<'l, T: Copy, const N: usize> Iterator for ArrayVecIter<'l, T, N> {
type Item = T;
crate::iterator::mk!();
}
impl<'l, T: Copy, const N: usize> FusedIterator for ArrayVecIter<'l, T, N> {}
impl<'l, T: Copy, const N: usize> ExactSizeIterator for ArrayVecIter<'l, T, N> {
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<'l, T: Copy, const N: usize> Clone for ArrayVecIter<'l, T, N> {
#[inline]
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<'l, T: Copy, const N: usize> core::fmt::Debug for ArrayVecIter<'l, T, N>
where
T: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
f.debug_list().entries(self.inner.clone()).finish()
}
}