package jetbrains.mps.internal.collections.runtime.impl;
/*Generated by MPS */
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.AbstractSequence;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LimitedCardinalitySequence<U> extends Sequence<U> {
private final AbstractSequence<U> input;
private final int maxCardinality;
public LimitedCardinalitySequence(AbstractSequence<U> input, int maxCardinality) {
if (input == null) {
throw new NullPointerException();
}
this.input = input;
this.maxCardinality = maxCardinality;
}
@Override
public Iterator<U> iterator() {
return new LimitedCardinalitySequence.LimitedCardinalityIterator();
}
private class LimitedCardinalityIterator implements Iterator<U> {
private Iterator<U> inputIt;
private CardinalityMap<U> cardMap;
private U next;
private HasNextState hasNext = HasNextState.UNKNOWN;
public LimitedCardinalityIterator() {
}
@Override
public boolean hasNext() {
if (inputIt == null) {
init();
}
if (hasNext.unknown()) {
moveToNext();
}
return hasNext.hasNext();
}
@Override
public U next() {
if (inputIt == null) {
init();
}
if (hasNext.unknown()) {
moveToNext();
}
if (!((hasNext.hasNext()))) {
throw new NoSuchElementException();
}
return clearNext();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private void moveToNext() {
next = null;
hasNext = HasNextState.AT_END;
while (inputIt.hasNext()) {
U tmp = inputIt.next();
if (cardMap.postInc(tmp) < maxCardinality) {
next = tmp;
hasNext = HasNextState.HAS_NEXT;
return;
}
}
cardMap.clear();
}
private U clearNext() {
U tmp = next;
next = null;
hasNext = HasNextState.UNKNOWN;
return tmp;
}
private void init() {
inputIt = input.iterator();
cardMap = new CardinalityMap<U>();
}
}
}