use core::iter::ExactSizeIterator; use core::iter::FusedIterator; use core::mem::MaybeUninit; #[derive(Clone)] pub(crate) struct ArrayVec { len: usize, array: [MaybeUninit; N], } impl ArrayVec { #[inline] pub(crate) fn new() -> Self { Self { len: 0, array: [const { MaybeUninit::uninit() }; N], } } #[inline] pub(crate) unsafe fn push_unchecked(&mut self, m: T) { debug_assert!(self.len < N); unsafe { self.array.get_unchecked_mut(self.len).write(m); self.len = self.len.unchecked_add(1); } } #[inline] pub(crate) fn len(&self) -> usize { self.len } #[inline] pub(crate) fn get(&self, index: usize) -> Option<&T> { if index < self.len { Some(unsafe { self.array.as_slice().get_unchecked(index).assume_init_ref() }) } else { None } } #[inline] pub(crate) fn as_slice_mut(&mut self) -> &mut [T] { unsafe { core::mem::transmute::<_, &mut [T]>(self.array.get_unchecked_mut(0..self.len)) } } } impl<'l, T: Copy, const N: usize> IntoIterator for &'l ArrayVec { type Item = T; type IntoIter = ArrayVecIter<'l, T, N>; #[inline] fn into_iter(self) -> Self::IntoIter { ArrayVecIter { array: self, index: 0, } } } pub(crate) struct ArrayVecIter<'l, T: Copy, const N: usize> { array: &'l ArrayVec, index: usize, } impl<'l, T: Copy, const N: usize> Iterator for ArrayVecIter<'l, T, N> { type Item = T; #[inline] fn next(&mut self) -> Option { if self.index < self.array.len { unsafe { let item = self .array .array .get_unchecked(self.index) .assume_init_read(); self.index = self.index.unchecked_add(1); Some(item) } } else { None } } #[inline] fn size_hint(&self) -> (usize, Option) { let len = self.len(); (len, Some(len)) } } 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 { unsafe { self.array.len().unchecked_sub(self.index) } } } impl IntoIterator for ArrayVec { type Item = T; type IntoIter = ArrayVecIntoIter; #[inline] fn into_iter(self) -> Self::IntoIter { ArrayVecIntoIter { array: self, index: 0, } } } pub(crate) struct ArrayVecIntoIter { array: ArrayVec, index: usize, } impl Iterator for ArrayVecIntoIter { type Item = T; #[inline] fn next(&mut self) -> Option { if self.index < self.array.len { unsafe { let item = self .array .array .get_unchecked(self.index) .assume_init_read(); self.index = self.index.unchecked_add(1); Some(item) } } else { None } } #[inline] fn size_hint(&self) -> (usize, Option) { let len = self.len(); (len, Some(len)) } } impl FusedIterator for ArrayVecIntoIter {} impl ExactSizeIterator for ArrayVecIntoIter { #[inline] fn len(&self) -> usize { unsafe { self.array.len().unchecked_sub(self.index) } } }