Skip to content

Commit f839b64

Browse files
authored
Add Java SimpleIterator goody (#165)
This makes it easy to implement an `Iterator` while providing only a `next()` method. The `hasNext()` method is then filled in for you via the `toIterator` method.
1 parent a68003e commit f839b64

File tree

7 files changed

+180
-3
lines changed

7 files changed

+180
-3
lines changed

tools/adventure-pack/goodies/java/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,9 @@ tasks.register<KtfmtFormatTask>("ktfmtCustom") {
4848
source = project.fileTree(rootDir)
4949
include("*.gradle.kts")
5050
}
51+
52+
tasks.withType<JavaCompile> {
53+
options.compilerArgs.add("-Xlint:all")
54+
options.compilerArgs.add("-Werror")
55+
options.isWarnings = true
56+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package simple_iterator;
2+
3+
import java.util.Iterator;
4+
import java.util.NoSuchElementException;
5+
6+
public interface SimpleIterator<T> {
7+
public T next();
8+
9+
static enum HasNextState {
10+
TRUE,
11+
FALSE,
12+
UNKNOWN,
13+
}
14+
15+
public static <T> Iterator<T> toIterator(final SimpleIterator<T> iterator) {
16+
final HasNextState[] hasNextState = { HasNextState.UNKNOWN };
17+
final Object[] elementReserve = { null };
18+
19+
return new Iterator<T>() {
20+
public boolean hasNext() {
21+
if (hasNextState[0] == HasNextState.UNKNOWN) {
22+
try {
23+
elementReserve[0] = iterator.next();
24+
hasNextState[0] = HasNextState.TRUE;
25+
} catch (NoSuchElementException e) {
26+
hasNextState[0] = HasNextState.FALSE;
27+
}
28+
}
29+
30+
return hasNextState[0] == HasNextState.TRUE;
31+
}
32+
33+
public T next() {
34+
if (hasNextState[0] == HasNextState.TRUE) {
35+
hasNextState[0] = HasNextState.UNKNOWN;
36+
37+
@SuppressWarnings("unchecked")
38+
T element = (T) elementReserve[0];
39+
40+
elementReserve[0] = null;
41+
return element;
42+
}
43+
44+
if (hasNextState[0] == HasNextState.UNKNOWN) {
45+
return iterator.next();
46+
}
47+
48+
throw new NoSuchElementException();
49+
}
50+
};
51+
}
52+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "SimpleIterator"
3+
}

tools/adventure-pack/goodies/java/src/to_iterable/AP.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
final class AP {
44

5-
public static <T> Iterable<T> toIterable(Iterator<T> iterator) {
5+
public static <T> Iterable<T> toIterable(final Iterator<T> iterator) {
66
return () -> iterator;
77
}
88
}

tools/adventure-pack/goodies/kotlin/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,5 @@ tasks.register<KtfmtFormatTask>("ktfmtCustom") {
4444
include("*.gradle.kts")
4545
include("**/*.kt")
4646
}
47+
48+
// TODO: Kotlin equivalent of -Xlint:all

tools/adventure-pack/src/app/__tests__/__snapshots__/equip-test.ts.snap

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,65 @@ record Pair<TFirst, TSecond>(TFirst first, TSecond second) {}
1010
/////////////////////////// END ADVENTURE PACK CODE ////////////////////////////"
1111
`;
1212

13+
exports[`App can equip single goody: Java SimpleIterator 1`] = `
14+
"////////////////////////// BEGIN ADVENTURE PACK CODE ///////////////////////////
15+
// Adventure Pack commit fake-commit-hash
16+
// Running at: https://example.com/
17+
18+
import java.util.Iterator;
19+
import java.util.NoSuchElementException;
20+
21+
interface SimpleIterator<T> {
22+
public T next();
23+
24+
static enum HasNextState {
25+
TRUE,
26+
FALSE,
27+
UNKNOWN,
28+
}
29+
30+
public static <T> Iterator<T> toIterator(final SimpleIterator<T> iterator) {
31+
final HasNextState[] hasNextState = { HasNextState.UNKNOWN };
32+
final Object[] elementReserve = { null };
33+
34+
return new Iterator<T>() {
35+
public boolean hasNext() {
36+
if (hasNextState[0] == HasNextState.UNKNOWN) {
37+
try {
38+
elementReserve[0] = iterator.next();
39+
hasNextState[0] = HasNextState.TRUE;
40+
} catch (NoSuchElementException e) {
41+
hasNextState[0] = HasNextState.FALSE;
42+
}
43+
}
44+
45+
return hasNextState[0] == HasNextState.TRUE;
46+
}
47+
48+
public T next() {
49+
if (hasNextState[0] == HasNextState.TRUE) {
50+
hasNextState[0] = HasNextState.UNKNOWN;
51+
52+
@SuppressWarnings("unchecked")
53+
T element = (T) elementReserve[0];
54+
55+
elementReserve[0] = null;
56+
return element;
57+
}
58+
59+
if (hasNextState[0] == HasNextState.UNKNOWN) {
60+
return iterator.next();
61+
}
62+
63+
throw new NoSuchElementException();
64+
}
65+
};
66+
}
67+
}
68+
69+
/////////////////////////// END ADVENTURE PACK CODE ////////////////////////////"
70+
`;
71+
1372
exports[`App can equip single goody: Java UnionFind 1`] = `
1473
"////////////////////////// BEGIN ADVENTURE PACK CODE ///////////////////////////
1574
// Adventure Pack commit fake-commit-hash
@@ -118,7 +177,7 @@ import java.util.Iterator;
118177
final class AP {
119178
private AP() {}
120179
121-
public static <T> Iterable<T> toIterable(Iterator<T> iterator) {
180+
public static <T> Iterable<T> toIterable(final Iterator<T> iterator) {
122181
return () -> iterator;
123182
}
124183
}

tools/adventure-pack/src/app/__tests__/__snapshots__/render-test.ts.snap

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,61 @@ exports[`App can render goody: Java Pair 1`] = `
66
record Pair<TFirst, TSecond>(TFirst first, TSecond second) {}"
77
`;
88

9+
exports[`App can render goody: Java SimpleIterator 1`] = `
10+
"package simple_iterator;
11+
12+
import java.util.Iterator;
13+
import java.util.NoSuchElementException;
14+
15+
interface SimpleIterator<T> {
16+
public T next();
17+
18+
static enum HasNextState {
19+
TRUE,
20+
FALSE,
21+
UNKNOWN,
22+
}
23+
24+
public static <T> Iterator<T> toIterator(final SimpleIterator<T> iterator) {
25+
final HasNextState[] hasNextState = { HasNextState.UNKNOWN };
26+
final Object[] elementReserve = { null };
27+
28+
return new Iterator<T>() {
29+
public boolean hasNext() {
30+
if (hasNextState[0] == HasNextState.UNKNOWN) {
31+
try {
32+
elementReserve[0] = iterator.next();
33+
hasNextState[0] = HasNextState.TRUE;
34+
} catch (NoSuchElementException e) {
35+
hasNextState[0] = HasNextState.FALSE;
36+
}
37+
}
38+
39+
return hasNextState[0] == HasNextState.TRUE;
40+
}
41+
42+
public T next() {
43+
if (hasNextState[0] == HasNextState.TRUE) {
44+
hasNextState[0] = HasNextState.UNKNOWN;
45+
46+
@SuppressWarnings("unchecked")
47+
T element = (T) elementReserve[0];
48+
49+
elementReserve[0] = null;
50+
return element;
51+
}
52+
53+
if (hasNextState[0] == HasNextState.UNKNOWN) {
54+
return iterator.next();
55+
}
56+
57+
throw new NoSuchElementException();
58+
}
59+
};
60+
}
61+
}"
62+
`;
63+
964
exports[`App can render goody: Java UnionFind 1`] = `
1065
"package union_find;
1166
@@ -86,7 +141,7 @@ import java.util.Iterator;
86141
final class AP {
87142
private AP() {}
88143
89-
public static <T> Iterable<T> toIterable(Iterator<T> iterator) {
144+
public static <T> Iterable<T> toIterable(final Iterator<T> iterator) {
90145
return () -> iterator;
91146
}
92147
}"

0 commit comments

Comments
 (0)