Skip to content

Commit 0fc99f1

Browse files
committed
Add an EnumSetIterator and EnumSet::iter
1 parent ca835f4 commit 0fc99f1

File tree

1 file changed

+83
-9
lines changed

1 file changed

+83
-9
lines changed

src/librustc/util/enum_set.rs

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use std::iterator::Iterator;
1112

1213
#[deriving(Eq, IterBytes)]
1314
pub struct EnumSet<E> {
@@ -73,6 +74,10 @@ impl<E:CLike> EnumSet<E> {
7374
}
7475
return true;
7576
}
77+
78+
pub fn iter(&self) -> EnumSetIterator<E> {
79+
EnumSetIterator::new(self.bits)
80+
}
7681
}
7782

7883
impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
@@ -93,6 +98,39 @@ impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
9398
}
9499
}
95100

101+
pub struct EnumSetIterator<E> {
102+
priv index: uint,
103+
priv bits: uint,
104+
}
105+
106+
impl<E:CLike> EnumSetIterator<E> {
107+
fn new(bits: uint) -> EnumSetIterator<E> {
108+
EnumSetIterator { index: 0, bits: bits }
109+
}
110+
}
111+
112+
impl<E:CLike> Iterator<E> for EnumSetIterator<E> {
113+
fn next(&mut self) -> Option<E> {
114+
if (self.bits == 0) {
115+
return None;
116+
}
117+
118+
while (self.bits & 1) == 0 {
119+
self.index += 1;
120+
self.bits >>= 1;
121+
}
122+
let elem = CLike::from_uint(self.index);
123+
self.index += 1;
124+
self.bits >>= 1;
125+
Some(elem)
126+
}
127+
128+
fn size_hint(&self) -> (Option<uint>, Option<uint>) {
129+
let exact = Some(self.bits.population_count());
130+
(exact, exact)
131+
}
132+
}
133+
96134
#[cfg(test)]
97135
mod test {
98136

@@ -199,25 +237,58 @@ mod test {
199237
}
200238

201239
///////////////////////////////////////////////////////////////////////////
202-
// each
240+
// iterator
241+
242+
#[test]
243+
fn test_iterator() {
244+
let mut e1: EnumSet<Foo> = EnumSet::empty();
245+
246+
let elems: ~[Foo] = e1.iter().collect();
247+
assert_eq!(~[], elems)
248+
249+
e1.add(A);
250+
let elems: ~[Foo] = e1.iter().collect();
251+
assert_eq!(~[A], elems)
252+
253+
e1.add(C);
254+
let elems: ~[Foo] = e1.iter().collect();
255+
assert_eq!(~[A,C], elems)
256+
257+
e1.add(C);
258+
let elems: ~[Foo] = e1.iter().collect();
259+
assert_eq!(~[A,C], elems)
260+
261+
e1.add(B);
262+
let elems: ~[Foo] = e1.iter().collect();
263+
assert_eq!(~[A,B,C], elems)
264+
}
265+
266+
fn collect(e: EnumSet<Foo>) -> ~[Foo] {
267+
let mut elems = ~[];
268+
e.each(|elem| {
269+
elems.push(elem);
270+
true
271+
});
272+
elems
273+
}
203274

204275
#[test]
205276
fn test_each() {
206277
let mut e1: EnumSet<Foo> = EnumSet::empty();
207278

208-
assert_eq!(~[], iter::FromIter::from_iter::<Foo, ~[Foo]>(|f| e1.each(f)))
279+
assert_eq!(~[], collect(e1))
209280

210281
e1.add(A);
211-
assert_eq!(~[A], iter::FromIter::from_iter::<Foo, ~[Foo]>(|f| e1.each(f)))
282+
assert_eq!(~[A], collect(e1))
212283

213284
e1.add(C);
214-
assert_eq!(~[A,C], iter::FromIter::from_iter::<Foo, ~[Foo]>(|f| e1.each(f)))
285+
assert_eq!(~[A,C], collect(e1))
215286

216287
e1.add(C);
217-
assert_eq!(~[A,C], iter::FromIter::from_iter::<Foo, ~[Foo]>(|f| e1.each(f)))
288+
assert_eq!(~[A,C], collect(e1))
218289

219290
e1.add(B);
220-
assert_eq!(~[A,B,C], iter::FromIter::from_iter::<Foo, ~[Foo]>(|f| e1.each(f)))
291+
assert_eq!(~[A,B,C], collect(e1))
221292
}
222293

223294
///////////////////////////////////////////////////////////////////////////
@@ -234,12 +305,15 @@ mod test {
234305
e2.add(C);
235306

236307
let e_union = e1 | e2;
237-
assert_eq!(~[A,B,C], iter::FromIter::from_iter::<Foo, ~[Foo]>(|f| e_union.each(f)))
308+
let elems: ~[Foo] = e_union.iter().collect();
309+
assert_eq!(~[A,B,C], elems)
238310

239311
let e_intersection = e1 & e2;
240-
assert_eq!(~[C], iter::FromIter::from_iter::<Foo, ~[Foo]>(|f| e_intersection.each(f)))
312+
let elems: ~[Foo] = e_intersection.iter().collect();
313+
assert_eq!(~[C], elems)
241314

242315
let e_subtract = e1 - e2;
243-
assert_eq!(~[A], iter::FromIter::from_iter::<Foo, ~[Foo]>(|f| e_subtract.each(f)))
316+
let elems: ~[Foo] = e_subtract.iter().collect();
317+
assert_eq!(~[A], elems)
244318
}
245319
}

0 commit comments

Comments
 (0)