7
7
* Simple iterator to cache the results of a generator so it can be iterated
8
8
* over multiple times
9
9
*
10
- * @template T
11
10
* @template S
12
- * @implements \Iterator<T, S>
11
+ * @implements \Iterator<S>
13
12
* @internal Do not use this in your code
14
13
* @psalm-immutable Not really immutable but to simplify declaring immutability of other structures
15
14
*/
16
15
final class Accumulate implements \Iterator
17
16
{
18
- /** @var \Generator<T, S> */
17
+ /** @var \Generator<S> */
19
18
private \Generator $ generator ;
20
- /** @var list<T> */
21
- private array $ keys = [];
22
19
/** @var list<S> */
23
20
private array $ values = [];
21
+ private bool $ started = false ;
24
22
25
23
/**
26
- * @param \Generator<T, S> $generator
24
+ * @param \Generator<S> $generator
27
25
*/
28
26
public function __construct (\Generator $ generator )
29
27
{
@@ -35,27 +33,31 @@ public function __construct(\Generator $generator)
35
33
*/
36
34
public function current (): mixed
37
35
{
36
+ /** @psalm-suppress InaccessibleProperty */
37
+ $ this ->started = true ;
38
38
/** @psalm-suppress UnusedMethodCall */
39
39
$ this ->pop ();
40
40
41
41
return \current ($ this ->values );
42
42
}
43
43
44
44
/**
45
- * @return T
45
+ * @return int<0, max>|null
46
46
*/
47
- public function key (): mixed
47
+ public function key (): ? int
48
48
{
49
+ /** @psalm-suppress InaccessibleProperty */
50
+ $ this ->started = true ;
49
51
/** @psalm-suppress UnusedMethodCall */
50
52
$ this ->pop ();
51
53
52
- return \current ($ this ->keys );
54
+ return \key ($ this ->values );
53
55
}
54
56
55
57
public function next (): void
56
58
{
57
59
/** @psalm-suppress InaccessibleProperty */
58
- \next ( $ this ->keys ) ;
60
+ $ this ->started = true ;
59
61
/** @psalm-suppress InaccessibleProperty */
60
62
\next ($ this ->values );
61
63
@@ -68,13 +70,15 @@ public function next(): void
68
70
public function rewind (): void
69
71
{
70
72
/** @psalm-suppress InaccessibleProperty */
71
- \reset ( $ this ->keys ) ;
73
+ $ this ->started = true ;
72
74
/** @psalm-suppress InaccessibleProperty */
73
75
\reset ($ this ->values );
74
76
}
75
77
76
78
public function valid (): bool
77
79
{
80
+ /** @psalm-suppress InaccessibleProperty */
81
+ $ this ->started = true ;
78
82
/** @psalm-suppress ImpureMethodCall */
79
83
$ valid = !$ this ->reachedCacheEnd () || $ this ->generator ->valid ();
80
84
@@ -88,6 +92,11 @@ public function valid(): bool
88
92
return $ valid ;
89
93
}
90
94
95
+ public function started (): bool
96
+ {
97
+ return $ this ->started ;
98
+ }
99
+
91
100
private function reachedCacheEnd (): bool
92
101
{
93
102
return \key ($ this ->values ) === null ;
@@ -96,11 +105,6 @@ private function reachedCacheEnd(): bool
96
105
private function pop (): void
97
106
{
98
107
if ($ this ->reachedCacheEnd ()) {
99
- /**
100
- * @psalm-suppress InaccessibleProperty
101
- * @psalm-suppress ImpureMethodCall
102
- */
103
- $ this ->keys [] = $ this ->generator ->key ();
104
108
/**
105
109
* @psalm-suppress InaccessibleProperty
106
110
* @psalm-suppress ImpureMethodCall
0 commit comments