• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.common.base;
16 
17 import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT;
18 import static com.google.common.base.Preconditions.checkState;
19 
20 import com.google.common.annotations.GwtCompatible;
21 import com.google.errorprone.annotations.CanIgnoreReturnValue;
22 import java.util.Iterator;
23 import java.util.NoSuchElementException;
24 import javax.annotation.CheckForNull;
25 import org.checkerframework.checker.nullness.qual.Nullable;
26 
27 /**
28  * Note this class is a copy of {@link com.google.common.collect.AbstractIterator} (for dependency
29  * reasons).
30  */
31 @GwtCompatible
32 @ElementTypesAreNonnullByDefault
33 abstract class AbstractIterator<T extends @Nullable Object> implements Iterator<T> {
34   private State state = State.NOT_READY;
35 
AbstractIterator()36   protected AbstractIterator() {}
37 
38   private enum State {
39     READY,
40     NOT_READY,
41     DONE,
42     FAILED,
43   }
44 
45   @CheckForNull private T next;
46 
47   @CheckForNull
computeNext()48   protected abstract T computeNext();
49 
50   @CanIgnoreReturnValue
51   @CheckForNull
endOfData()52   protected final T endOfData() {
53     state = State.DONE;
54     return null;
55   }
56 
57   @Override
hasNext()58   public final boolean hasNext() {
59     checkState(state != State.FAILED);
60     switch (state) {
61       case DONE:
62         return false;
63       case READY:
64         return true;
65       default:
66     }
67     return tryToComputeNext();
68   }
69 
tryToComputeNext()70   private boolean tryToComputeNext() {
71     state = State.FAILED; // temporary pessimism
72     next = computeNext();
73     if (state != State.DONE) {
74       state = State.READY;
75       return true;
76     }
77     return false;
78   }
79 
80   @Override
81   @ParametricNullness
next()82   public final T next() {
83     if (!hasNext()) {
84       throw new NoSuchElementException();
85     }
86     state = State.NOT_READY;
87     // Safe because hasNext() ensures that tryToComputeNext() has put a T into `next`.
88     T result = uncheckedCastNullableTToT(next);
89     next = null;
90     return result;
91   }
92 
93   @Override
remove()94   public final void remove() {
95     throw new UnsupportedOperationException();
96   }
97 }
98