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