Skip to content

Commit 6a43fc6

Browse files
author
blake2-ppc
committed
extra: External iterators for TreeSet set operations
Write external iterators for Difference, Sym. Difference, Intersection and Union set operations. These iterators are generic insofar that they could work on any ordered sequence iterators, even though they are type specialized to the TreeSetIterator in this case. Looking at the `check` function in the treeset tests, rustc seems unwilling to compile a function resembling:: fn check<'a, T: Iterator<&'a int>>(... ) so the tests for these iterators are still running the legacy loop protocol.
1 parent d5ef318 commit 6a43fc6

File tree

1 file changed

+134
-114
lines changed

1 file changed

+134
-114
lines changed

src/libextra/treemap.rs

Lines changed: 134 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -433,20 +433,7 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> {
433433
/// Return true if the set has no elements in common with `other`.
434434
/// This is equivalent to checking for an empty intersection.
435435
fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
436-
let mut x = self.iter();
437-
let mut y = other.iter();
438-
let mut a = x.next();
439-
let mut b = y.next();
440-
while a.is_some() && b.is_some() {
441-
let a1 = a.unwrap();
442-
let b1 = b.unwrap();
443-
match a1.cmp(b1) {
444-
Less => a = x.next(),
445-
Greater => b = y.next(),
446-
Equal => return false
447-
}
448-
}
449-
true
436+
self.intersection(other).next().is_none()
450437
}
451438

452439
/// Return true if the set is a subset of another
@@ -526,131 +513,164 @@ impl<T: TotalOrd> TreeSet<T> {
526513
}
527514

528515
/// Visit the values (in-order) representing the difference
529-
pub fn difference(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) -> bool {
530-
let mut x = self.iter();
531-
let mut y = other.iter();
516+
pub fn difference<'a>(&'a self, other: &'a TreeSet<T>) -> Difference<'a, T> {
517+
Difference{a: Focus::new(self.iter()), b: Focus::new(other.iter())}
518+
}
532519

533-
let mut a = x.next();
534-
let mut b = y.next();
520+
/// Visit the values (in-order) representing the symmetric difference
521+
pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet<T>)
522+
-> SymDifference<'a, T> {
523+
SymDifference{a: Focus::new(self.iter()), b: Focus::new(other.iter())}
524+
}
535525

536-
while a.is_some() {
537-
if b.is_none() {
538-
return f(a.unwrap()) && x.advance(f);
539-
}
526+
/// Visit the values (in-order) representing the intersection
527+
pub fn intersection<'a>(&'a self, other: &'a TreeSet<T>)
528+
-> Intersection<'a, T> {
529+
Intersection{a: Focus::new(self.iter()), b: Focus::new(other.iter())}
530+
}
540531

541-
let a1 = a.unwrap();
542-
let b1 = b.unwrap();
532+
/// Visit the values (in-order) representing the union
533+
pub fn union<'a>(&'a self, other: &'a TreeSet<T>) -> Union<'a, T> {
534+
Union{a: Focus::new(self.iter()), b: Focus::new(other.iter())}
535+
}
536+
}
543537

544-
let cmp = a1.cmp(b1);
538+
/// Lazy forward iterator over a set
539+
pub struct TreeSetIterator<'self, T> {
540+
priv iter: TreeMapIterator<'self, T, ()>
541+
}
545542

546-
if cmp == Less {
547-
if !f(a1) { return false; }
548-
a = x.next();
549-
} else {
550-
if cmp == Equal { a = x.next() }
551-
b = y.next();
552-
}
553-
}
554-
return true;
555-
}
543+
// Encapsulate an iterator and hold its latest value until stepped forward
544+
struct Focus<A, T> {
545+
priv iter: T,
546+
priv focus: Option<A>,
547+
}
556548

557-
/// Visit the values (in-order) representing the symmetric difference
558-
pub fn symmetric_difference(&self, other: &TreeSet<T>,
559-
f: &fn(&T) -> bool) -> bool {
560-
let mut x = self.iter();
561-
let mut y = other.iter();
549+
impl<A, T: Iterator<A>> Focus<A, T> {
550+
fn new(mut it: T) -> Focus<A, T> {
551+
Focus{focus: it.next(), iter: it}
552+
}
553+
fn step(&mut self) {
554+
self.focus = self.iter.next()
555+
}
556+
}
562557

563-
let mut a = x.next();
564-
let mut b = y.next();
558+
/// Lazy iterator producing elements in the set difference (in-order)
559+
pub struct Difference<'self, T> {
560+
priv a: Focus<&'self T, TreeSetIterator<'self, T>>,
561+
priv b: Focus<&'self T, TreeSetIterator<'self, T>>,
562+
}
565563

566-
while a.is_some() {
567-
if b.is_none() {
568-
return f(a.unwrap()) && x.advance(f);
569-
}
564+
/// Lazy iterator producing elements in the set symmetric difference (in-order)
565+
pub struct SymDifference<'self, T> {
566+
priv a: Focus<&'self T, TreeSetIterator<'self, T>>,
567+
priv b: Focus<&'self T, TreeSetIterator<'self, T>>,
568+
}
570569

571-
let a1 = a.unwrap();
572-
let b1 = b.unwrap();
570+
/// Lazy iterator producing elements in the set intersection (in-order)
571+
pub struct Intersection<'self, T> {
572+
priv a: Focus<&'self T, TreeSetIterator<'self, T>>,
573+
priv b: Focus<&'self T, TreeSetIterator<'self, T>>,
574+
}
573575

574-
let cmp = a1.cmp(b1);
576+
/// Lazy iterator producing elements in the set intersection (in-order)
577+
pub struct Union<'self, T> {
578+
priv a: Focus<&'self T, TreeSetIterator<'self, T>>,
579+
priv b: Focus<&'self T, TreeSetIterator<'self, T>>,
580+
}
575581

576-
if cmp == Less {
577-
if !f(a1) { return false; }
578-
a = x.next();
579-
} else {
580-
if cmp == Greater {
581-
if !f(b1) { return false; }
582-
} else {
583-
a = x.next();
582+
impl<'self, T: TotalOrd> Iterator<&'self T> for Difference<'self, T> {
583+
fn next(&mut self) -> Option<&'self T> {
584+
loop {
585+
match (self.a.focus, self.b.focus) {
586+
(None , _ ) => return None,
587+
(ret , None ) => { self.a.step(); return ret },
588+
(Some(a1), Some(b1)) => {
589+
let cmp = a1.cmp(b1);
590+
if cmp == Less {
591+
self.a.step();
592+
return Some(a1);
593+
} else {
594+
if cmp == Equal { self.a.step() }
595+
self.b.step();
596+
}
584597
}
585-
b = y.next();
586598
}
587599
}
588-
b.iter().advance(|&x| f(x)) && y.advance(f)
589600
}
601+
}
590602

591-
/// Visit the values (in-order) representing the intersection
592-
pub fn intersection(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) -> bool {
593-
let mut x = self.iter();
594-
let mut y = other.iter();
595-
596-
let mut a = x.next();
597-
let mut b = y.next();
598-
599-
while a.is_some() && b.is_some() {
600-
let a1 = a.unwrap();
601-
let b1 = b.unwrap();
602-
603-
let cmp = a1.cmp(b1);
604-
605-
if cmp == Less {
606-
a = x.next();
607-
} else {
608-
if cmp == Equal {
609-
if !f(a1) { return false }
603+
impl<'self, T: TotalOrd> Iterator<&'self T> for SymDifference<'self, T> {
604+
fn next(&mut self) -> Option<&'self T> {
605+
loop {
606+
match (self.a.focus, self.b.focus) {
607+
(ret , None ) => { self.a.step(); return ret },
608+
(None , ret ) => { self.b.step(); return ret },
609+
(Some(a1), Some(b1)) => {
610+
let cmp = a1.cmp(b1);
611+
if cmp == Less {
612+
self.a.step();
613+
return Some(a1);
614+
} else {
615+
self.b.step();
616+
if cmp == Greater {
617+
return Some(b1);
618+
} else {
619+
self.a.step();
620+
}
621+
}
610622
}
611-
b = y.next();
612623
}
613624
}
614-
return true;
615625
}
626+
}
616627

617-
/// Visit the values (in-order) representing the union
618-
pub fn union(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) -> bool {
619-
let mut x = self.iter();
620-
let mut y = other.iter();
621-
622-
let mut a = x.next();
623-
let mut b = y.next();
624-
625-
while a.is_some() {
626-
if b.is_none() {
627-
return f(a.unwrap()) && x.advance(f);
628+
impl<'self, T: TotalOrd> Iterator<&'self T> for Intersection<'self, T> {
629+
fn next(&mut self) -> Option<&'self T> {
630+
loop {
631+
match (self.a.focus, self.b.focus) {
632+
(None , _ ) => return None,
633+
(_ , None ) => return None,
634+
(Some(a1), Some(b1)) => {
635+
let cmp = a1.cmp(b1);
636+
if cmp == Less {
637+
self.a.step();
638+
} else {
639+
self.b.step();
640+
if cmp == Equal {
641+
return Some(a1);
642+
}
643+
}
644+
},
628645
}
646+
}
647+
}
648+
}
629649

630-
let a1 = a.unwrap();
631-
let b1 = b.unwrap();
632-
633-
let cmp = a1.cmp(b1);
634-
635-
if cmp == Greater {
636-
if !f(b1) { return false; }
637-
b = y.next();
638-
} else {
639-
if !f(a1) { return false; }
640-
if cmp == Equal {
641-
b = y.next();
650+
impl<'self, T: TotalOrd> Iterator<&'self T> for Union<'self, T> {
651+
fn next(&mut self) -> Option<&'self T> {
652+
loop {
653+
match (self.a.focus, self.b.focus) {
654+
(ret , None) => { self.a.step(); return ret },
655+
(None , ret ) => { self.b.step(); return ret },
656+
(Some(a1), Some(b1)) => {
657+
let cmp = a1.cmp(b1);
658+
if cmp == Greater {
659+
self.b.step();
660+
return Some(b1);
661+
} else {
662+
self.a.step();
663+
if cmp == Equal {
664+
self.b.step();
665+
}
666+
return Some(a1);
667+
}
642668
}
643-
a = x.next();
644669
}
645670
}
646-
b.iter().advance(|&x| f(x)) && y.advance(f)
647671
}
648672
}
649673

650-
/// Lazy forward iterator over a set
651-
pub struct TreeSetIterator<'self, T> {
652-
priv iter: TreeMapIterator<'self, T, ()>
653-
}
654674

655675
// Nodes keep track of their level in the tree, starting at 1 in the
656676
// leaves and with a red child sharing the level of the parent.
@@ -1426,7 +1446,7 @@ mod test_set {
14261446
#[test]
14271447
fn test_intersection() {
14281448
fn check_intersection(a: &[int], b: &[int], expected: &[int]) {
1429-
check(a, b, expected, |x, y, z| x.intersection(y, z))
1449+
check(a, b, expected, |x, y, f| x.intersection(y).advance(f))
14301450
}
14311451

14321452
check_intersection([], [], []);
@@ -1442,7 +1462,7 @@ mod test_set {
14421462
#[test]
14431463
fn test_difference() {
14441464
fn check_difference(a: &[int], b: &[int], expected: &[int]) {
1445-
check(a, b, expected, |x, y, z| x.difference(y, z))
1465+
check(a, b, expected, |x, y, f| x.difference(y).advance(f))
14461466
}
14471467

14481468
check_difference([], [], []);
@@ -1460,7 +1480,7 @@ mod test_set {
14601480
fn test_symmetric_difference() {
14611481
fn check_symmetric_difference(a: &[int], b: &[int],
14621482
expected: &[int]) {
1463-
check(a, b, expected, |x, y, z| x.symmetric_difference(y, z))
1483+
check(a, b, expected, |x, y, f| x.symmetric_difference(y).advance(f))
14641484
}
14651485

14661486
check_symmetric_difference([], [], []);
@@ -1475,7 +1495,7 @@ mod test_set {
14751495
fn test_union() {
14761496
fn check_union(a: &[int], b: &[int],
14771497
expected: &[int]) {
1478-
check(a, b, expected, |x, y, z| x.union(y, z))
1498+
check(a, b, expected, |x, y, f| x.union(y).advance(f))
14791499
}
14801500

14811501
check_union([], [], []);

0 commit comments

Comments
 (0)