package com.codepoetics.protonpack;
import java.util.Spliterator;
import java.util.function.BiFunction;
import java.util.function.Consumer;
class ZippingSpliterator<L, R, O> implements Spliterator<O> {
static <L, R, O> Spliterator<O> zipping(Spliterator<L> lefts, Spliterator<R> rights, BiFunction<L, R, O> combiner) {
return new ZippingSpliterator<>(lefts, rights, combiner);
}
private final Spliterator<L> lefts;
private final Spliterator<R> rights;
private final BiFunction<L, R, O> combiner;
private boolean rightHadNext = false;
private ZippingSpliterator(Spliterator<L> lefts, Spliterator<R> rights, BiFunction<L, R, O> combiner) {
this.lefts = lefts;
this.rights = rights;
this.combiner = combiner;
}
@Override
public boolean tryAdvance(Consumer<? super O> action) {
rightHadNext = false;
boolean leftHadNext = lefts.tryAdvance(l ->
rights.tryAdvance(r -> {
rightHadNext = true;
action.accept(combiner.apply(l, r));
}));
return leftHadNext && rightHadNext;
}
@Override
public Spliterator<O> trySplit() {
return null;
}
@Override
public long estimateSize() {
return Math.min(lefts.estimateSize(), rights.estimateSize());
}
@Override
public int characteristics() {
return lefts.characteristics() & rights.characteristics()
& ~(Spliterator.DISTINCT | Spliterator.SORTED);
}
}