#![warn(missing_docs)]
extern crate streaming_iterator;
use streaming_iterator::{StreamingIterator,StreamingIteratorMut};
use std::ops::{AddAssign,SubAssign};
use std::cmp::{Ord,Ordering};
pub trait Streaming: StreamingIterator+Sized {
fn enumerate(self) -> Enumerate<Self> {
Enumerate {count: 0, it: self}
}
fn zip<J: StreamingIterator>(self, j: J) -> Zip<Self,J> {
Zip {i: self, j}
}
fn map_ref_and<F,R,T>(self, f: F) -> MapRefAnd<Self,F,R,T>
where F: for<'a> FnMut(&'a Self::Item) -> RefAnd<'a,R,T> {
MapRefAnd {it: self, f, inner: None}
}
fn map_mut_and<F,R,T>(self, f: F) -> MapMutRefAnd<Self,F,R,T>
where F: for<'a> FnMut(&'a mut Self::Item) -> MutRefAnd<'a,R,T> {
MapMutRefAnd {it: self, f, inner: None}
}
fn combinations_with<'a,J,F>(&'a mut self, mut f: F)
-> MutRefAnd<'a,Self,Combinations<J,F>>
where J: StreamingIterator, F: FnMut() -> J {
self.advance();
MutRefAnd {r: self, other: Combinations {j: f(),f}}
}
fn inner_combinations<T,F,S>(mut self, mut target: T, f: F, mut stack: S)
-> InnerCombinations<T,F,S>
where Self: Clone, F: Fn(&Self::Item) -> T, S: Stack<Item=Self>,
T: AddAssign<T> + SubAssign<T> + Ord + Clone {
if let Some(first) = self.next() {
target -= f(first);
} else {
return InnerCombinations {f,target,stack}
}
stack.try_push(self);
InnerCombinations {f,target,stack}
}
fn cfilter<F: FnMut(&Self::Item)->bool>(self,f:F) -> CFilter<Self,F> {
CFilter{it: self, f}
}
fn cmap<F: FnMut(&Self::Item)->B,B>(self,f:F) -> CMap<Self,F,B> {
CMap {it: self, f, b: None}
}
fn cflat_map<F,J>(self, f:F) -> CFlatMap<Self,F,J>
where J: StreamingIterator, F: FnMut(&Self::Item) -> J {
CFlatMap {it: self, f, j: None}
}
}
#[derive(Debug,Clone)]
pub struct Enumerate<I: StreamingIterator> {
count: usize,
it: I,
}
impl<I: StreamingIterator> StreamingIterator for Enumerate<I> {
type Item = Self;
#[inline]fn advance(&mut self) {
self.it.advance();
self.count += 1;
}
#[inline]fn get(&self) -> Option<&Self::Item> {
if self.it.is_done() {None} else {Some(self)}
}
#[inline]fn is_done(&self) -> bool {self.it.is_done()}
}
impl<I: StreamingIteratorMut> StreamingIteratorMut for Enumerate<I> {
#[inline]fn get_mut(&mut self) -> Option<&mut Self::Item> {
if self.it.is_done() {None} else {Some(self)}
}
}
impl<I: StreamingIterator> Enumerate<I> {
#[inline]pub fn unwrap<'a>(&'a self) -> (usize, &'a I::Item) {
(self.count-1, self.it.get().unwrap())
}
}
impl<I: StreamingIteratorMut> Enumerate<I> {
#[inline]pub fn unwrap_mut<'a>(&'a mut self) -> (usize, &'a mut I::Item) {
(self.count-1, self.it.get_mut().unwrap())
}
}
#[derive(Debug,Clone)]
pub struct Zip<I,J> {i: I, j: J}
impl<I,J> StreamingIterator for Zip<I,J>
where I: StreamingIterator, J: StreamingIterator {
type Item = Self;
#[inline]fn advance(&mut self) {self.i.advance();self.j.advance();}
#[inline]fn get(&self) -> Option<&Self::Item> {
(!(self.is_done())).then_some(self)
}
#[inline]fn is_done(&self) -> bool {self.i.is_done() || self.j.is_done()}
}
impl<I,J> StreamingIteratorMut for Zip<I,J>
where I: StreamingIteratorMut, J: StreamingIteratorMut {
#[inline]fn get_mut(&mut self) -> Option<&mut Self::Item> {
(!(self.is_done())).then_some(self)
}
}
impl<I,J> Zip<I,J>
where I: StreamingIterator, J: StreamingIterator {
#[inline]pub fn unwrap(&self) -> (&I::Item, &J::Item) {
(self.i.get().unwrap(),self.j.get().unwrap())
}
}
impl<I,J> Zip<I,J>
where I: StreamingIteratorMut, J: StreamingIteratorMut {
#[inline]pub fn unwrap_mut(&mut self) -> (&mut I::Item, &mut J::Item) {
(self.i.get_mut().unwrap(),self.j.get_mut().unwrap())
}
}
#[derive(Debug)]
pub struct RefAnd<'a,R,T> {r: &'a R, other: T}
impl<'a,R:'static,T> RefAnd<'a,R,T> {
#[inline]unsafe fn to_static(self) -> RefAnd<'static,R,T> {
let RefAnd{r,other} = self;
RefAnd{ r: &*(r as *const R), other}
}
#[inline]pub fn new(r: &'a R, other: T) -> Self {Self {r,other}}
#[inline]pub fn unwrap<'b>(&'b self) -> (&'b R, &'b T) {
(self.r,&self.other)
}
}
#[derive(Debug)]
pub struct MapRefAnd<I,F,R:'static,T> {
it: I, f: F, inner: Option<RefAnd<'static,R,T>>
}
impl<I,F,R: 'static,T> StreamingIterator for MapRefAnd<I,F,R,T>
where I: StreamingIterator, F: for<'a> FnMut(&'a I::Item) -> RefAnd<'a,R,T> {
type Item = RefAnd<'static,R,T>;
#[inline]fn advance(&mut self) {
self.inner = self.it.next().map(|next| unsafe {
((self.f)(next)).to_static()
});
}
#[inline]fn get(&self) -> Option<&Self::Item> {
self.inner.as_ref()
}
}
impl<I,F,R,T> Clone for MapRefAnd<I,F,R,T>
where I: StreamingIterator+Clone, T: Clone,
F: Clone+for<'a> Fn(&'a I::Item) -> RefAnd<'a,R,T>, {
fn clone(&self) -> Self {
let it = self.it.clone();
let f = self.f.clone();
let inner = if let Some(ref inner) = self.inner {
Some(RefAnd{r: unsafe {f(it.get().unwrap()).to_static()}.r,
other: inner.other.clone()})
} else {None};
Self {it,f,inner}
}
}
#[derive(Debug)]
pub struct MutRefAnd<'a,R,T> {r: &'a mut R, other: T}
impl<'a,R:'static,T> MutRefAnd<'a,R,T> {
#[inline]unsafe fn to_static(self) -> MutRefAnd<'static,R,T> {
let MutRefAnd{r,other} = self;
MutRefAnd{ r: &mut *(r as *mut R), other}
}
#[inline]pub fn new(r: &'a mut R, other: T) -> Self {Self {r,other}}
#[inline]pub fn unwrap<'b>(&'b self) -> (&'b R, &'b T) {
(self.r,&self.other)
}
#[inline]pub fn unwrap_mut<'b>(&'b mut self) -> (&'b mut R, &'b mut T) {
(self.r,&mut self.other)
}
}
#[derive(Debug)]
pub struct MapMutRefAnd<I,F,R:'static,T> {
it: I, f: F, inner: Option<MutRefAnd<'static,R,T>>
}
impl<I,F,R: 'static,T> StreamingIterator for MapMutRefAnd<I,F,R,T>
where I: StreamingIteratorMut,
F: for<'a> FnMut(&'a mut I::Item) -> MutRefAnd<'a,R,T> {
type Item = MutRefAnd<'static,R,T>;
#[inline]fn advance(&mut self) {
self.inner = self.it.next_mut().map(|next| unsafe {
((self.f)(next)).to_static()
});
}
#[inline]fn get(&self) -> Option<&Self::Item> {
self.inner.as_ref()
}
}
impl<I,F,R: 'static,T> StreamingIteratorMut for MapMutRefAnd<I,F,R,T>
where I: StreamingIteratorMut,
F: for<'a> FnMut(&'a mut I::Item) -> MutRefAnd<'a,R,T> {
#[inline]fn get_mut(&mut self) -> Option<&mut Self::Item> {
self.inner.as_mut()
}
}
impl<I,F,R,T> Clone for MapMutRefAnd<I,F,R,T>
where I: StreamingIteratorMut+Clone, T: Clone,
F: Clone+for<'a> Fn(&'a mut I::Item) -> MutRefAnd<'a,R,T>, {
fn clone(&self) -> Self {
let mut it = self.it.clone();
let f = self.f.clone();
let inner = if let Some(ref inner) = self.inner {
Some(MutRefAnd{r: unsafe {f(it.get_mut().unwrap()).to_static()}.r,
other: inner.other.clone()})
} else {None};
Self {it,f,inner}
}
}
#[derive(Debug,Clone)]
pub struct Combinations<J,F> {j: J, f: F}
impl<'a,I,J,F> StreamingIterator for MutRefAnd<'a,I,Combinations<J,F>>
where I: StreamingIterator, J: StreamingIterator, F: FnMut() -> J {
type Item = Self;
#[inline]fn advance(&mut self) {
self.other.j.advance();
if !(self.other.j.is_done()) {return}
self.r.advance();
self.other.j = (self.other.f)();
self.other.j.advance();
}
#[inline]fn get(&self) -> Option<&Self::Item> {
(!(self.is_done())).then_some(self)
}
#[inline]fn is_done(&self) -> bool {
self.r.is_done() || self.other.j.is_done()
}
}
impl<'a,I,J,F> MutRefAnd<'a,I,Combinations<J,F>>
where I: StreamingIterator, J: StreamingIterator {
#[inline]pub fn unwrap_full<'b>(&'b self) -> (&'b I::Item, &'b J::Item) {
(self.r.get().unwrap(),self.other.j.get().unwrap())
}
}
#[derive(Debug,Clone)]
pub struct CFilter<I,F> {
it: I, f: F
}
impl<I,F> StreamingIterator for CFilter<I,F>
where I:StreamingIterator,F: FnMut(&I::Item) -> bool {
type Item = I::Item;
#[inline]fn advance(&mut self) {
while let Some(i) = self.it.next() {if (self.f)(i) {break}}
}
#[inline]fn is_done(&self) -> bool {self.it.is_done()}
#[inline]fn get(&self) -> Option<&I::Item> {self.it.get()}
#[inline]fn size_hint(&self)->(usize, Option<usize>){
(0, self.it.size_hint().1)
}
}
#[derive(Debug,Clone)]
pub struct CMap<I,F,B> {it: I, f: F, b: Option<B>}
impl<I,F,B> StreamingIterator for CMap<I,F,B>
where I: StreamingIterator, F: FnMut(&I::Item) -> B {
type Item = B;
#[inline]fn advance(&mut self) {self.b=self.it.next().map(&mut self.f);}
#[inline]fn get(&self) -> Option<&B> {self.b.as_ref()}
#[inline]fn size_hint(&self) -> (usize, Option<usize>) {self.it.size_hint()}
}
impl<I,F,B> StreamingIteratorMut for CMap<I,F,B>
where I: StreamingIterator, F: FnMut(&I::Item) -> B {
#[inline]fn get_mut(&mut self) -> Option<&mut B> {self.b.as_mut()}
}
#[derive(Debug,Clone)]
pub struct CFlatMap<I,F,J> {it: I, f: F, j: Option<J>}
impl<I,F,J> StreamingIterator for CFlatMap<I,F,J>
where I: StreamingIterator, F: FnMut(&I::Item) -> J, J: StreamingIterator {
type Item = J::Item;
#[inline]fn advance(&mut self) { loop {
if let Some(ref mut iter) = self.j {
iter.advance();
if !iter.is_done() {break}
}
if let Some(item) = self.it.next() {
self.j = Some((self.f)(item));
} else {break}
}}
#[inline]fn is_done(&self) -> bool {
match self.j {Some(ref iter) => iter.is_done(),None => true}
}
#[inline]fn get(&self) -> Option<&Self::Item> {
self.j.as_ref().and_then(J::get)
}
}
impl<I: StreamingIterator> Streaming for I {}
#[derive(Debug,Clone)]
pub struct InnerCombinations<T,F,S> {
f: F,
target: T,
stack: S,
}
impl<I,T,F,S> StreamingIterator for InnerCombinations<T,F,S>
where I: StreamingIterator+Clone, F: Fn(&I::Item) -> T, S: Stack<Item=I>,
T: AddAssign<T> + SubAssign<T> + Ord + Clone {
type Item = S;
fn advance(&mut self) {
while !(self.stack.is_empty()) {
let last_len = (self.f)(self.stack.get().unwrap().get().unwrap());
match last_len.cmp(&self.target) {
Ordering::Greater => {},
order => {
if self.stack.try_push(self.stack.get().unwrap().clone()) {
self.target -= last_len;
if order.is_eq() {return} else {continue}
}
},
}
loop {
let last_len = (self.f)(self.stack.get().unwrap().get().unwrap());
self.target += last_len;
let new_len = self.stack.get_mut().unwrap().next().map(&self.f);
match new_len.as_ref().map_or(Ordering::Greater,
|l| l.cmp(&self.target)) {
Ordering::Greater => {
self.stack.pop();
if self.stack.is_empty() {return}
},
order => {
self.target -= new_len.unwrap();
if order.is_eq() {return} else {break}
}
}
}
}
}
fn get(&self) -> Option<&Self::Item> {
if self.stack.is_empty() {None} else {
Some(&self.stack)
}
}
}
pub trait Stack {
type Item;
fn try_push(&mut self, elem: Self::Item) -> bool;
fn pop(&mut self) -> Option<Self::Item>;
fn get(&self) -> Option<&Self::Item>;
fn get_mut(&mut self) -> Option<&mut Self::Item>;
fn is_empty(&self) -> bool;
}
impl<T> Stack for Vec<T> {
type Item=T;
fn try_push(&mut self, elem: T) -> bool {self.push(elem);true}
fn pop(&mut self) -> Option<T> {self.pop()}
fn get(&self) -> Option<&T> {self.last()}
fn get_mut(&mut self) -> Option<&mut T> {self.last_mut()}
fn is_empty(&self) -> bool {self.is_empty()}
}