roaring 0.0.15

http://roaringbitmap.org for http://www.rust-lang.org
use std::{ u16 };
use std::slice::Iter;

use util::Either;
use util::Either::{ Left, Right };
use container::{ Container, ContainerIter };

pub struct RoaringIterator<'a> {
    inner_iter: Option<(u16, ContainerIter<'a>)>,
    container_iter: Box<Iter<'a, Container>>,
}

fn calc(key: u16, value: u16) -> u32 {
    ((key as u32) << u16::BITS) + (value as u32)
}

fn find_next_iter<'a>(container_iter: &mut Iter<'a, Container>) -> Option<(u16, ContainerIter<'a>)> {
    match container_iter.next() {
        Some(container) => Some((container.key(), container.iter())),
        None => None
    }
}

impl<'a> RoaringIterator<'a> {
    pub fn new(mut container_iter: Box<Iter<'a, Container>>) -> RoaringIterator<'a> {
        RoaringIterator {
            inner_iter: find_next_iter(&mut *container_iter),
            container_iter: container_iter
        }
    }

    fn choose_next(&mut self) -> Option<Either<u32, Option<(u16, ContainerIter<'a>)>>> {
        match self.inner_iter {
            Some((key, ref mut iter)) => Some(match *iter {
                ContainerIter::ArrayIter(ref mut iter) => match iter.next() {
                    Some(value) => Left(calc(key, *value)),
                    None => Right(find_next_iter(&mut *self.container_iter)),
                },
                ContainerIter::BitmapIter(ref mut iter) => match iter.next() {
                    Some(value) => Left(calc(key, value)),
                    None => Right(find_next_iter(&mut *self.container_iter)),
                },
            }),
            None => None,
        }
    }
}

impl<'a> Iterator<u32> for RoaringIterator<'a> {
    fn next(&mut self) -> Option<u32> {
        match self.choose_next() {
            None => None,
            Some(Left(val)) => Some(val),
            Some(Right(new_iter)) => {
                self.inner_iter = new_iter;
                self.next()
            },
        }
    }
}