"An implementation of `Set` that wraps an `Iterable` of
elements. All operations on this `Set` are performed
on the `Iterable`."
by ("Enrique Zamudio")
shared class LazySet<out Element>({Element*} elems)
satisfies Set<Element>
given Element satisfies Object {
shared actual LazySet<Element> clone => this;
shared actual Integer size {
variable value c=0;
value sorted = elems.sort(byIncreasing((Element e) => e.hash));
if (exists l=sorted.first) {
c=1;
variable Element last = l;
for (e in sorted.rest) {
if (e!=last) {
c++;
last=e;
}
}
}
return c;
}
shared actual Iterator<Element> iterator() {
object iterator satisfies Iterator<Element> {
value sorted = elems.sort(byIncreasing((Element e) => e.hash)).iterator();
variable Element|Finished ready = sorted.next();
shared actual Element|Finished next() {
Element|Finished next = ready;
if (!is Finished next) {
while (next==ready) {
ready = sorted.next();
}
}
return next;
}
}
return iterator;
}
shared actual Set<Element|Other> union<Other>(Set<Other> set)
given Other satisfies Object =>
LazySet(elems.chain(set));
shared actual Set<Element&Other> intersection<Other>(Set<Other> set)
given Other satisfies Object =>
//requires support for reified generics!
LazySet ({ for (e in set) if (is Element e, e in this) e });
shared actual Set<Element|Other> exclusiveUnion<Other>(Set<Other> other)
given Other satisfies Object {
value hereNotThere = { for (e in elems) if (!e in other) e };
value thereNotHere = { for (e in other) if (!e in this) e };
return LazySet(hereNotThere.chain(thereNotHere));
}
shared actual Set<Element> complement<Other>(Set<Other> set)
given Other satisfies Object =>
LazySet ({ for (e in this) if (!e in set) e });
shared actual default Boolean equals(Object that) {
if (is Set<Object> that) {
if (that.size==size) {
for (element in elems) {
if (!element in that) {
return false;
}
}
else {
return true;
}
}
}
return false;
}
shared actual default Integer hash {
variable Integer hashCode = 1;
for(elem in elems){
hashCode *= 31;
hashCode += elem.hash;
}
return hashCode;
}
}