use crate::bits::Bits;
use crate::word::Word;
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Positions<W: Word>(pub(crate) W);
impl<W: Word> Iterator for Positions<W> {
type Item = u32;
#[inline]
fn next(&mut self) -> Option<u32> {
let p = self.0.first_set()?;
self.0 = self.0.clear_lowest_set();
Some(p)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.0.count_ones() as usize;
(n, Some(n))
}
}
impl<W: Word> DoubleEndedIterator for Positions<W> {
#[inline]
fn next_back(&mut self) -> Option<u32> {
let p = self.0.last_set()?;
self.0 = self.0.xor(W::ONE.shl(p));
Some(p)
}
}
impl<W: Word> ExactSizeIterator for Positions<W> {}
impl<W: Word> core::iter::FusedIterator for Positions<W> {}
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Subsets<W: Word> {
mask: W,
next: Option<W>,
}
impl<W: Word> Subsets<W> {
#[inline]
pub(crate) const fn new(mask: W) -> Self {
Self {
mask,
next: Some(W::ZERO),
}
}
}
impl<W: Word> Iterator for Subsets<W> {
type Item = W;
#[inline]
fn next(&mut self) -> Option<W> {
let current = self.next?;
self.next = current.next_subset(self.mask);
Some(current)
}
}
impl<W: Word> core::iter::FusedIterator for Subsets<W> {}