use core::fmt;
use core::fmt::Debug;
use core::iter::FusedIterator;
use crate::adaptors::generic_combinations::GenericCombinations;
pub trait IterCombinations: Iterator {
#[inline]
fn combinations(self, k: usize) -> Combinations<Self>
where
Self: Sized,
Self::Item: Clone,
{
Combinations::new(self, k)
}
}
impl<I: ?Sized> IterCombinations for I where I: Iterator {}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Combinations<I>(GenericCombinations<I, Vec<usize>>)
where
I: Iterator;
impl<I> Combinations<I>
where
I: Iterator,
I::Item: Clone,
{
#[track_caller]
pub(crate) fn new(iter: I, k: usize) -> Self {
assert!(k != 0, "combination size must be non-zero");
Self(GenericCombinations::new(iter, Vec::from_iter(0..k)))
}
}
impl<I> Clone for Combinations<I>
where
I: Iterator + Clone,
I::Item: Clone,
{
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<I> Debug for Combinations<I>
where
I: Iterator + Debug,
I::Item: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt_with(f, "Combinations")
}
}
impl<I> Iterator for Combinations<I>
where
I: Iterator,
I::Item: Clone,
{
type Item = Vec<I::Item>;
fn next(&mut self) -> Option<Self::Item> {
self.0.fill_next().map(Vec::from_iter)
}
}
impl<I> FusedIterator for Combinations<I>
where
I: Iterator,
I::Item: Clone,
{
}