use std::mem;
pub trait Merge<I: Iterator> {
fn merge(self) -> MergeIterator<I>;
}
impl<I: Iterator, I2: Iterator<Item=I>> Merge<I> for I2 where I::Item: Ord {
fn merge(self) -> MergeIterator<I> {
let mut merge = MergeIterator::new();
merge.renew(self);
merge
}
}
pub struct MergeIterator<I: Iterator> {
heap: Vec<(I::Item, I)>,
}
impl<I: Iterator> MergeIterator<I> where I::Item: Ord {
pub fn new() -> MergeIterator<I> {
MergeIterator { heap: Vec::new() }
}
pub fn renew<I2: Iterator<Item=I>>(&mut self, iters: I2) {
self.heap.clear();
for mut iter in iters {
if let Some(next) = iter.next() {
self.heap.push((next, iter));
}
}
let len = self.heap.len();
for i in 0..self.heap.len() {
self.sift_down(len - i - 1);
}
}
#[inline]
fn sift_down(&mut self, mut index: usize) {
let mut child = 2 * index + 1;
while child < self.heap.len() {
let other = child + 1;
if other < self.heap.len() && self.heap[child].0 > self.heap[other].0 {
child = other;
}
if self.heap[child].0 < self.heap[index].0 {
self.heap.swap(child, index);
index = child;
child = 2 * index + 1;
}
else { return; }
}
}
}
impl<I: Iterator> Iterator for MergeIterator<I> where I::Item: Ord {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
if self.heap.len() > 0 {
let result = if let Some(mut next) = self.heap[0].1.next() {
mem::swap(&mut next, &mut self.heap[0].0);
next
}
else {
self.heap.swap_remove(0).0
};
self.sift_down(0);
Some(result)
}
else { None }
}
}
pub trait MergeUsing<I: Iterator> {
fn merge_using<'a>(self, heap: &'a mut Vec<(I::Item, I)>) -> MergeUsingIterator<'a, I>;
}
impl<I: Iterator, I2: Iterator<Item=I>> MergeUsing<I> for I2 where I::Item: Ord {
fn merge_using<'a>(self, heap: &'a mut Vec<(I::Item, I)>) -> MergeUsingIterator<'a, I> {
MergeUsingIterator::new(self, heap)
}
}
pub struct MergeUsingIterator<'a, I: Iterator+'a> where I::Item: 'a {
heap: &'a mut Vec<(I::Item, I)>,
}
impl<'a, I: Iterator+'a> MergeUsingIterator<'a, I> where I::Item: Ord+'a {
pub fn new<I2: Iterator<Item=I>>(iters: I2, heap: &'a mut Vec<(I::Item, I)>) -> MergeUsingIterator<'a, I> {
heap.clear();
let mut result = MergeUsingIterator { heap: heap };
for mut iter in iters {
if let Some(next) = iter.next() {
result.heap.push((next, iter));
}
}
let len = result.heap.len();
for i in 0..result.heap.len() {
result.sift_down(len - i - 1);
}
result
}
#[inline]
fn sift_down(&mut self, mut index: usize) {
let mut child = 2 * index + 1;
while child < self.heap.len() {
let other = child + 1;
if other < self.heap.len() && self.heap[child].0 > self.heap[other].0 {
child = other;
}
if self.heap[child].0 < self.heap[index].0 {
self.heap.swap(child, index);
index = child;
child = 2 * index + 1;
}
else { return; }
}
}
}
impl<'a, I: Iterator+'a> Iterator for MergeUsingIterator<'a, I> where I::Item: Ord+'a {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
if self.heap.len() > 0 {
let result = if let Some(mut next) = self.heap[0].1.next() {
mem::swap(&mut next, &mut self.heap[0].0);
next
}
else {
self.heap.swap_remove(0).0
};
self.sift_down(0);
Some(result)
}
else { None }
}
}