Implement .iter and .into_iter. Closes #1.

This commit is contained in:
2018-01-05 20:54:47 +01:00
parent ab66c25813
commit 1de9a0904d

View File

@@ -1,7 +1,7 @@
extern crate unreachable;
use std::ops;
use std::iter::FromIterator;
use std::iter::{Iterator, IntoIterator, FromIterator};
use std::default::Default;
use std::collections::HashMap;
@@ -132,6 +132,103 @@ impl BitSet {
pub fn is_superset(&self, other: &BitSet) -> bool {
other.is_subset(self)
}
pub fn iter(&self) -> Iter {
Iter { iter: self.blocks.iter(), block: 0, bits: 0, bit: BITS }
}
}
pub struct Iter<'a> {
iter: std::collections::hash_map::Iter<'a, u64, u64>,
block: u64,
bits: u64,
bit: u64,
}
impl<'a> Iterator for Iter<'a> {
type Item = u64;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
loop {
if self.bits == 0 || self.bit == BITS {
match self.iter.next() {
Some((block, bits)) => {
self.block = *block;
self.bits = *bits;
self.bit = 0;
}
None => return None,
}
}
for i in self.bit..BITS {
if self.bits & (1 << i) != 0 {
self.bit = i + 1;
return Some((self.block * BITS) + i);
}
}
self.bit = BITS;
}
}
}
pub struct IntoIter {
iter: std::collections::hash_map::IntoIter<u64, u64>,
block: u64,
bits: u64,
bit: u64,
}
impl Iterator for IntoIter {
type Item = u64;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
loop {
if self.bits == 0 || self.bit == BITS {
match self.iter.next() {
Some((block, bits)) => {
self.block = block;
self.bits = bits;
self.bit = 0;
}
None => return None,
}
}
for i in self.bit..BITS {
if self.bits & (1 << i) != 0 {
self.bit = i + 1;
return Some((self.block * BITS) + i);
}
}
self.bit = BITS;
}
}
}
impl<'a> IntoIterator for &'a BitSet {
type Item = u64;
type IntoIter = Iter<'a>;
fn into_iter(self) -> Iter<'a> {
self.iter()
}
}
impl IntoIterator for BitSet {
type Item = u64;
type IntoIter = IntoIter;
fn into_iter(self) -> IntoIter {
IntoIter { iter: self.blocks.into_iter(), block: 0, bits: 0, bit: BITS }
}
}
impl Default for BitSet {
@@ -284,4 +381,28 @@ mod tests {
set.insert(4);
assert_eq!(set.is_subset(&sup), false);
}
#[test]
fn iter() {
let set = [1, 2, 3].iter().cloned().collect::<BitSet>();
let mut iter = set.iter();
assert_eq!(Some(1), iter.next());
assert_eq!(Some(2), iter.next());
assert_eq!(Some(3), iter.next());
assert_eq!(None, iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn into_iter() {
let set = [1, 2, 3].iter().cloned().collect::<BitSet>();
let mut iter = set.into_iter();
assert_eq!(Some(1), iter.next());
assert_eq!(Some(2), iter.next());
assert_eq!(Some(3), iter.next());
assert_eq!(None, iter.next());
assert_eq!(None, iter.next());
}
}