| 1 | package pro.verron.officestamper.utils.iterator; | |
| 2 | ||
| 3 | import org.jspecify.annotations.Nullable; | |
| 4 | ||
| 5 | import java.util.NoSuchElementException; | |
| 6 | ||
| 7 | /// A [ResetableIterator] implementation that provides a sliced view of another iterator. It allows iteration over a | |
| 8 | /// subset of elements from a source iterator, defined by a start and end element. | |
| 9 | /// | |
| 10 | /// @param <T> the type of elements returned by this iterator | |
| 11 | public class SlicingIterator<T> | |
| 12 | implements ResetableIterator<T> { | |
| 13 | private final ResetableIterator<T> source; | |
| 14 | private final T start; | |
| 15 | private final T end; | |
| 16 | private @Nullable T next; | |
| 17 | private boolean foundStart = false; | |
| 18 | private boolean foundEnd = false; | |
| 19 | ||
| 20 | ||
| 21 | /// Constructs a new SlicingIterator with the specified source iterator and boundaries. | |
| 22 | /// | |
| 23 | /// @param source the underlying [ResetableIterator] to slice | |
| 24 | /// @param start the starting element (inclusive) for iteration | |
| 25 | /// @param end the ending element (inclusive) for iteration | |
| 26 | public SlicingIterator(ResetableIterator<T> source, T start, T end) { | |
| 27 | this.source = source; | |
| 28 | this.start = start; | |
| 29 | this.end = end; | |
| 30 |
1
1. <init> : removed call to pro/verron/officestamper/utils/iterator/SlicingIterator::findNext → NO_COVERAGE |
findNext(); |
| 31 | } | |
| 32 | ||
| 33 | private void findNext() { | |
| 34 | next = null; | |
| 35 |
2
1. findNext : negated conditional → NO_COVERAGE 2. findNext : negated conditional → NO_COVERAGE |
while (source.hasNext() && !foundStart) { |
| 36 | var o = source.next(); | |
| 37 |
1
1. findNext : negated conditional → NO_COVERAGE |
if (o == start) { |
| 38 | foundStart = true; | |
| 39 | next = o; | |
| 40 | } | |
| 41 | } | |
| 42 | ||
| 43 |
2
1. findNext : negated conditional → NO_COVERAGE 2. findNext : negated conditional → NO_COVERAGE |
if (source.hasNext() && !foundEnd) { |
| 44 | next = source.next(); | |
| 45 |
1
1. findNext : negated conditional → NO_COVERAGE |
if (next == end) foundEnd = true; |
| 46 | } | |
| 47 | } | |
| 48 | ||
| 49 | @Override | |
| 50 | public void reset() { | |
| 51 |
1
1. reset : removed call to pro/verron/officestamper/utils/iterator/ResetableIterator::reset → NO_COVERAGE |
source.reset(); |
| 52 | foundStart = false; | |
| 53 | foundEnd = false; | |
| 54 |
1
1. reset : removed call to pro/verron/officestamper/utils/iterator/SlicingIterator::findNext → NO_COVERAGE |
findNext(); |
| 55 | } | |
| 56 | ||
| 57 | @Override | |
| 58 | public boolean hasNext() { | |
| 59 |
2
1. hasNext : negated conditional → NO_COVERAGE 2. hasNext : replaced boolean return with true for pro/verron/officestamper/utils/iterator/SlicingIterator::hasNext → NO_COVERAGE |
return next != null; |
| 60 | } | |
| 61 | ||
| 62 | @Override | |
| 63 | public T next() { | |
| 64 |
1
1. next : negated conditional → NO_COVERAGE |
if (next == null) throw new NoSuchElementException("No more elements to iterate"); |
| 65 | T result = next; | |
| 66 |
1
1. next : removed call to pro/verron/officestamper/utils/iterator/SlicingIterator::findNext → NO_COVERAGE |
findNext(); |
| 67 |
1
1. next : replaced return value with null for pro/verron/officestamper/utils/iterator/SlicingIterator::next → NO_COVERAGE |
return result; |
| 68 | } | |
| 69 | } | |
Mutations | ||
| 30 |
1.1 |
|
| 35 |
1.1 2.2 |
|
| 37 |
1.1 |
|
| 43 |
1.1 2.2 |
|
| 45 |
1.1 |
|
| 51 |
1.1 |
|
| 54 |
1.1 |
|
| 59 |
1.1 2.2 |
|
| 64 |
1.1 |
|
| 66 |
1.1 |
|
| 67 |
1.1 |