use alloc::boxed::Box;
pub type BoxIter<'a, T> = Box<dyn Iterator<Item = T> + 'a>;
pub fn box_once<'a, T: 'a>(x: T) -> BoxIter<'a, T> {
Box::new(core::iter::once(x))
}
pub fn map_with<'a, T: Clone + 'a, U: 'a, V: 'a>(
mut l: impl Iterator<Item = U> + 'a,
x: T,
r: impl Fn(U, T) -> V + 'a,
) -> BoxIter<'a, V> {
if l.size_hint().1 == Some(1) {
if let Some(ly) = l.next() {
assert!(l.next().is_none());
return box_once(r(ly, x));
}
}
Box::new(l.map(move |ly| r(ly, x.clone())))
}
pub fn flat_map_with<'a, T: Clone + 'a, U: 'a, V: 'a>(
mut l: impl Iterator<Item = U> + 'a,
x: T,
r: impl Fn(U, T) -> BoxIter<'a, V> + 'a,
) -> BoxIter<'a, V> {
if l.size_hint().1 == Some(1) {
if let Some(ly) = l.next() {
assert!(l.next().is_none());
return Box::new(r(ly, x));
}
}
Box::new(l.flat_map(move |ly| r(ly, x.clone())))
}