pub struct Combinations<'a, T, F, I, E: Clone> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
sources: &'a [T],
f: F,
iterators: Vec<I>,
elements: Vec<E>,
visited: bool
}
impl<'a, T, F, I, E: Clone> Combinations<'a, T, F, I, E> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
pub fn new(sources: &'a [T], f: F) -> Combinations<'a, T, F, I, E> {
let iterators = if sources.is_empty() {
Vec::new()
} else {
vec![(f)(&sources[0])]
};
Combinations {
sources: sources,
f: f,
iterators: iterators,
elements: Vec::new(),
visited: false
}
}
}
impl<'a, T, F, I, E: Clone> Iterator for Combinations<'a, T, F, I, E> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
type Item = Vec<E>;
fn next(&mut self) -> Option<Self::Item> {
if self.sources.is_empty() {
if self.visited {
None
} else {
self.visited = true;
Some(Vec::new())
}
} else {
while self.elements.len() < self.sources.len() {
match self.iterators.last_mut().unwrap().next() {
Some(e) => {
self.elements.push(e);
let j = self.elements.len();
if j < self.sources.len() {
self.iterators.push((self.f)(&self.sources[j]))
}
},
None => {
match self.elements.pop() {
Some(_) => {
self.iterators.pop();
},
None => return None
}
}
}
}
let item = self.elements.clone();
self.elements.pop();
Some(item)
}
}
}
pub fn combinations<'a, T, F, I, E: Clone>(sources: &'a [T], f: F) -> Combinations<'a, T, F, I, E> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
Combinations::new(sources, f)
}
pub struct CombinationsOption<'a, T, F, I, E: Clone> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
sources: &'a [T],
f: F,
iterators: Vec<(I, bool)>,
elements: Vec<Option<E>>,
visited: bool,
weak: bool
}
impl<'a, T, F, I, E: Clone> CombinationsOption<'a, T, F, I, E> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
pub fn new(sources: &'a [T], f: F, weak: bool) -> CombinationsOption<'a, T, F, I, E> {
let iterators = if sources.is_empty() {
Vec::new()
} else {
vec![((f)(&sources[0]), false)]
};
CombinationsOption {
sources: sources,
f: f,
iterators: iterators,
elements: Vec::new(),
visited: false,
weak: weak
}
}
}
impl<'a, T, F, I, E: Clone> Iterator for CombinationsOption<'a, T, F, I, E> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
type Item = Vec<Option<E>>;
fn next(&mut self) -> Option<Self::Item> {
if self.sources.is_empty() {
if self.visited {
None
} else {
self.visited = true;
Some(Vec::new())
}
} else {
while self.elements.len() < self.sources.len() {
match self.iterators.last_mut() {
Some((ref mut it, ref mut visited)) => {
match it.next() {
Some(e) => {
self.elements.push(Some(e));
if !self.weak {
*visited = true;
}
let j = self.elements.len();
if j < self.sources.len() {
self.iterators.push(((self.f)(&self.sources[j]), false))
}
},
None => {
if *visited {
match self.elements.pop() {
Some(_) => {
self.iterators.pop();
},
None => {
return None
}
}
} else {
self.elements.push(None);
*visited = true;
let j = self.elements.len();
if j < self.sources.len() {
self.iterators.push(((self.f)(&self.sources[j]), false))
}
}
}
};
},
None => unreachable!()
}
}
let item = self.elements.clone();
self.elements.pop();
Some(item)
}
}
}
pub fn combinations_option<'a, T, F, I, E: Clone>(sources: &'a [T], f: F) -> CombinationsOption<'a, T, F, I, E> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
CombinationsOption::new(sources, f, false)
}
pub fn combinations_weak_option<'a, T, F, I, E: Clone>(sources: &'a [T], f: F) -> CombinationsOption<'a, T, F, I, E> where F: Fn(&'a T) -> I, I: 'a + Iterator<Item=E> {
CombinationsOption::new(sources, f, true)
}
pub struct Mux<T: Iterator> {
iterators: Vec<T>,
index: usize
}
impl<T: Iterator> Mux<T> {
pub fn new(iterators: Vec<T>) -> Mux<T> {
Mux {
iterators: iterators,
index: 0
}
}
}
impl<T: Iterator> Iterator for Mux<T> {
type Item = T::Item;
fn next(&mut self) -> Option<T::Item> {
if self.iterators.is_empty() {
None
} else {
let mut i = self.index;
loop {
if let Some(item) = self.iterators[i].next() {
self.index = (i + 1)%self.iterators.len();
return Some(item)
} else {
i = (i + 1)%self.iterators.len();
if i == self.index {
return None
}
}
}
}
}
}