pub trait Heuristic: Clone {
type Iter: Iterator<Item = bool>;
fn enter(&mut self, side: bool);
fn iter(&self) -> Self::Iter;
}
pub trait IntoHeuristic {
type Heuristic: Heuristic;
fn into_heuristic(self) -> Self::Heuristic;
}
impl<H> IntoHeuristic for H
where
H: Heuristic,
{
type Heuristic = Self;
#[inline(always)]
fn into_heuristic(self) -> Self {
self
}
}
#[derive(Clone)]
pub struct FilterHeuristic<F>(pub F);
impl<F> Heuristic for FilterHeuristic<F>
where
F: FnMut(bool) -> bool + Clone,
{
type Iter = FilterHeuristicIter<F>;
#[inline(always)]
fn enter(&mut self, side: bool) {
self.0(side);
}
#[inline(always)]
fn iter(&self) -> Self::Iter {
FilterHeuristicIter {
f: self.0.clone(),
iter: [false, true].iter(),
}
}
}
#[doc(hidden)]
pub struct FilterHeuristicIter<F> {
f: F,
iter: std::slice::Iter<'static, bool>,
}
impl<F> Iterator for FilterHeuristicIter<F>
where
F: FnMut(bool) -> bool + Clone,
{
type Item = bool;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
let f = self.f.clone();
(&mut self.iter).cloned().find(move |&n| (f.clone())(n))
}
}
#[derive(Clone)]
pub struct SearchHeuristic<F>(pub F, pub bool);
impl<F> Heuristic for SearchHeuristic<F>
where
F: FnMut(bool) -> bool + Clone,
{
type Iter = std::iter::Cloned<std::slice::Iter<'static, bool>>;
#[inline(always)]
fn enter(&mut self, side: bool) {
self.1 = self.0(side);
}
#[inline(always)]
fn iter(&self) -> Self::Iter {
if self.1 {
[true, false].iter().cloned()
} else {
[false, true].iter().cloned()
}
}
}