eschac 0.5.0

computing chess moves
Documentation
use core::iter::ExactSizeIterator;
use core::iter::FusedIterator;
use core::mem::MaybeUninit;

#[derive(Clone)]
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 = unsafe { self.array.get_unchecked(0..self.len) };
        unsafe { core::mem::transmute::<&[MaybeUninit<T>], &[T]>(t) }
    }
    #[inline]
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        let t = unsafe { self.array.get_unchecked_mut(0..self.len) };
        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().into_iter().copied(),
        }
    }
}

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()
    }
}
impl<T: Copy, const N: usize> Default for ArrayVec<T, N> {
    #[inline]
    fn default() -> Self {
        Self::new()
    }
}
impl<T: Copy, const N: usize> PartialEq for ArrayVec<T, N>
where
    T: PartialEq,
{
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.as_slice().eq(other.as_slice())
    }
    #[inline]
    fn ne(&self, other: &Self) -> bool {
        self.as_slice().ne(other.as_slice())
    }
}
impl<T: Copy, const N: usize> Eq for ArrayVec<T, N> where T: Eq {}
impl<T: Copy, const N: usize> PartialOrd for ArrayVec<T, N>
where
    T: PartialOrd,
{
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
        self.as_slice().partial_cmp(other.as_slice())
    }
}
impl<T: Copy, const N: usize> Ord for ArrayVec<T, N>
where
    T: Ord,
{
    #[inline]
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        self.as_slice().cmp(other.as_slice())
    }
}
impl<T: Copy, const N: usize> core::hash::Hash for ArrayVec<T, N>
where
    T: core::hash::Hash,
{
    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
        self.as_slice().hash(state)
    }
}

#[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().into_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().into_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().into_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()
    }
}