package com.codepoetics.protonpack; import java.util.Comparator; import java.util.Spliterator; import java.util.function.Consumer; import java.util.function.Predicate; class TakeWhileSpliterator<T> implements Spliterator<T> { static <T> TakeWhileSpliterator<T> over(Spliterator<T> source, Predicate<T> condition) { return new TakeWhileSpliterator<>(source, condition, false); } static <T> TakeWhileSpliterator<T> overInclusive(Spliterator<T> source, Predicate<T> condition) { return new TakeWhileSpliterator<>(source, condition, true); } private final Spliterator<T> source; private final Predicate<T> condition; private final boolean inclusive; private boolean conditionHeldSoFar = true; private TakeWhileSpliterator(Spliterator<T> source, Predicate<T> condition, boolean inclusive) { this.source = source; this.condition = condition; this.inclusive = inclusive; } @Override public boolean tryAdvance(Consumer<? super T> action) { return conditionHeldSoFar && source.tryAdvance(e -> { if (condition.test(e)) { action.accept(e); } else { if (inclusive && conditionHeldSoFar) { action.accept(e); } conditionHeldSoFar = false; } }); } @Override public Spliterator<T> trySplit() { return null; } @Override public long estimateSize() { return conditionHeldSoFar ? source.estimateSize() : 0; } @Override public int characteristics() { return source.characteristics() &~ Spliterator.SIZED; } @Override public Comparator<? super T> getComparator() { return source.getComparator(); } }