107 lines
2.7 KiB
Rust
107 lines
2.7 KiB
Rust
use core::iter::ExactSizeIterator;
|
|
use core::iter::FusedIterator;
|
|
use core::mem::MaybeUninit;
|
|
|
|
pub(crate) struct ArrayVec<T, const N: usize> {
|
|
len: usize,
|
|
array: [MaybeUninit<T>; N],
|
|
}
|
|
|
|
impl<T, const N: usize> Clone for ArrayVec<T, N>
|
|
where
|
|
T: Copy,
|
|
{
|
|
#[inline]
|
|
fn clone(&self) -> Self {
|
|
Self {
|
|
len: self.len,
|
|
array: self.array.clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T, const N: usize> ArrayVec<T, N> {
|
|
#[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(&self) -> &[T] {
|
|
unsafe { core::mem::transmute::<_, &[T]>(self.array.get_unchecked(0..self.len)) }
|
|
}
|
|
#[inline]
|
|
pub(crate) fn as_mut_slice(&mut self) -> &mut [T] {
|
|
unsafe { core::mem::transmute::<_, &mut [T]>(self.array.get_unchecked_mut(0..self.len)) }
|
|
}
|
|
}
|
|
|
|
impl<T, const N: usize> IntoIterator for ArrayVec<T, N> {
|
|
type Item = T;
|
|
type IntoIter = ArrayVecIntoIter<T, N>;
|
|
#[inline]
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
ArrayVecIntoIter {
|
|
array: self,
|
|
index: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(crate) struct ArrayVecIntoIter<T, const N: usize> {
|
|
array: ArrayVec<T, N>,
|
|
index: usize,
|
|
}
|
|
impl<T, const N: usize> Iterator for ArrayVecIntoIter<T, N> {
|
|
type Item = T;
|
|
#[inline]
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
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<usize>) {
|
|
let len = self.len();
|
|
(len, Some(len))
|
|
}
|
|
}
|
|
impl<T, const N: usize> FusedIterator for ArrayVecIntoIter<T, N> {}
|
|
impl<T, const N: usize> ExactSizeIterator for ArrayVecIntoIter<T, N> {
|
|
#[inline]
|
|
fn len(&self) -> usize {
|
|
unsafe { self.array.len().unchecked_sub(self.index) }
|
|
}
|
|
}
|