use core::array::IntoIter;
use core::fmt;
use core::ops::{Deref, DerefMut};
use crate::Move;
#[cfg(target_pointer_width = "64")]
const MAX_MOVES: usize = 252;
#[cfg(target_pointer_width = "32")]
const MAX_MOVES: usize = 254;
#[cfg(target_pointer_width = "16")]
const MAX_MOVES: usize = 255;
#[derive(Clone, Debug)]
pub struct MoveList {
moves: [Move; MAX_MOVES],
len: usize,
}
impl IntoIterator for MoveList {
type Item = Move;
type IntoIter = core::iter::Take<IntoIter<Move, MAX_MOVES>>;
fn into_iter(self) -> Self::IntoIter {
IntoIterator::into_iter(self.moves).take(self.len)
}
}
impl<'a> IntoIterator for &'a MoveList {
type Item = &'a Move;
type IntoIter = core::slice::Iter<'a, Move>;
fn into_iter(self) -> Self::IntoIter {
self.moves[..self.len].iter()
}
}
impl Deref for MoveList {
type Target = [Move];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl DerefMut for MoveList {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_slice()
}
}
impl Default for MoveList {
#[inline]
fn default() -> Self {
MoveList {
moves: [Move::null(); MAX_MOVES],
len: 0,
}
}
}
impl fmt::Display for MoveList {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_empty() {
return write!(f, "MoveList: (0 moves)");
}
writeln!(f, "MoveList ({} moves):", self.len)?;
for (index, mv) in self.moves.iter().take(self.len).enumerate() {
writeln!(f, "{}: {}", index + 1, mv)?;
}
Ok(())
}
}
impl MoveList {
#[inline(always)]
pub fn push(&mut self, mv: Move) {
if self.len < MAX_MOVES {
self.moves[self.len] = mv;
self.len += 1;
}
}
#[inline(always)]
pub fn as_slice(&self) -> &[Move] {
&self.moves[..self.len]
}
#[inline(always)]
pub fn as_mut_slice(&mut self) -> &mut [Move] {
&mut self.moves[0..self.len]
}
#[inline(always)]
pub fn len(&self) -> usize {
self.len
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline(always)]
pub fn clear(&mut self) {
self.len = 0;
}
}