// TreeSet variant allowing multiple elements which are considered
// equal by the comparator but not by eq().
// All operations O(log n) with n being the number of _different_ elements.
sclass TreeSetWithDuplicates extends AbstractSet {
NavigableSet> internal;
Comparator comparator;
int size;
*() { internal = new TreeSet; }
*(Comparator *comparator) {
internal = new TreeSet>((setA, setB) -> {
ret comparator.compare(main first(setA), main first(setB));
});
}
protected *(NavigableSet> *internal) {}
/*swappable*/ CompactLinkedHashSet makeInternalSet() {
ret new CompactLinkedHashSet;
}
public bool add(A a) {
CompactLinkedHashSet newSet = addAndReturnCollection(makeInternalSet(), a);
CompactLinkedHashSet found = navigableSet_find(internal, newSet);
if (found != null) {
if (!found.add(a)) false;
} else
internal.add(newSet);
++size;
true;
}
public bool remove(O a) {
CompactLinkedHashSet newSet = addAndReturnCollection(makeInternalSet(), (A) a);
CompactLinkedHashSet found = navigableSet_find(internal, newSet);
if (found == null) false;
if (l(found) == 1)
internal.remove(found);
else
found.remove(a);
--size;
true;
}
A first() {
ret main first(main first(internal));
}
A last() {
var last = internal.last();
ret last?.last();
}
public ItIt iterator() {
ret nestedIterator(internal, methodLambda0 iterator);
}
public int size() { ret size; }
// may return null
Set tiedForFirst() { ret main first(internal); }
public bool contains(O a) {
Set newSet = addAndReturnCollection(makeInternalSet(), (A) a);
ret navigableSet_find(internal, newSet) != null;
}
}