use std::cmp::Ordering;
use std::fmt::Write;
use crate::IdxSize;
pub mod enumerate_idx;
pub mod zip_eq;
pub use enumerate_idx::EnumerateIdx;
pub use zip_eq::{ZipEq, zip_eq};
pub trait Itertools: Iterator {
fn collect_vec(self) -> Vec<Self::Item>
where
Self: Sized,
{
self.collect()
}
fn try_collect<T, U, E>(self) -> Result<U, E>
where
Self: Sized + Iterator<Item = Result<T, E>>,
Result<U, E>: FromIterator<Result<T, E>>,
{
self.collect()
}
fn try_collect_vec<T, U, E>(self) -> Result<Vec<U>, E>
where
Self: Sized + Iterator<Item = Result<T, E>>,
Result<Vec<U>, E>: FromIterator<Result<T, E>>,
{
self.collect()
}
fn enumerate_idx(self) -> EnumerateIdx<Self, IdxSize>
where
Self: Sized,
{
EnumerateIdx::new(self)
}
fn enumerate_u32(self) -> EnumerateIdx<Self, u32>
where
Self: Sized,
{
EnumerateIdx::new(self)
}
fn all_equal(mut self) -> bool
where
Self: Sized,
Self::Item: PartialEq,
{
match self.next() {
None => true,
Some(a) => self.all(|x| a == x),
}
}
fn eq_by_<I, F>(mut self, other: I, mut eq: F) -> bool
where
Self: Sized,
I: IntoIterator,
F: FnMut(Self::Item, I::Item) -> bool,
{
let mut other = other.into_iter();
loop {
match (self.next(), other.next()) {
(None, None) => return true,
(None, Some(_)) => return false,
(Some(_), None) => return false,
(Some(l), Some(r)) => {
if eq(l, r) {
continue;
} else {
return false;
}
},
}
}
}
fn partial_cmp_by_<I, F>(mut self, other: I, mut partial_cmp: F) -> Option<Ordering>
where
Self: Sized,
I: IntoIterator,
F: FnMut(Self::Item, I::Item) -> Option<Ordering>,
{
let mut other = other.into_iter();
loop {
match (self.next(), other.next()) {
(None, None) => return Some(Ordering::Equal),
(None, Some(_)) => return Some(Ordering::Less),
(Some(_), None) => return Some(Ordering::Greater),
(Some(l), Some(r)) => match partial_cmp(l, r) {
Some(Ordering::Equal) => continue,
ord => return ord,
},
}
}
}
fn join(&mut self, sep: &str) -> String
where
Self::Item: std::fmt::Display,
{
match self.next() {
None => String::new(),
Some(first_elt) => {
let (lower, _) = self.size_hint();
let mut result = String::with_capacity(sep.len() * lower);
write!(&mut result, "{}", first_elt).unwrap();
self.for_each(|elt| {
result.push_str(sep);
write!(&mut result, "{}", elt).unwrap();
});
result
},
}
}
fn zip_eq<I>(self, other: I) -> ZipEq<Self, I::IntoIter>
where
Self: Sized,
I: IntoIterator,
{
zip_eq(self, other)
}
}
impl<T: Iterator + ?Sized> Itertools for T {}