5
5
namespace Doctrine \ODM \MongoDB \Iterator ;
6
6
7
7
use Countable ;
8
- use Generator ;
8
+ use Iterator as SPLIterator ;
9
+ use IteratorIterator ;
9
10
use ReturnTypeWillChange ;
10
11
use RuntimeException ;
11
12
use Traversable ;
@@ -33,13 +34,11 @@ final class CachingIterator implements Countable, Iterator
33
34
/** @var array<mixed, TValue> */
34
35
private array $ items = [];
35
36
36
- /** @var Generator <mixed, TValue>|null */
37
- private ?Generator $ iterator ;
37
+ /** @var SPLIterator <mixed, TValue>|null */
38
+ private ?SPLIterator $ iterator ;
38
39
39
40
private bool $ iteratorAdvanced = false ;
40
41
41
- private bool $ iteratorExhausted = false ;
42
-
43
42
/**
44
43
* Initialize the iterator and stores the first item in the cache. This
45
44
* effectively rewinds the Traversable and the wrapping Generator, which
@@ -51,7 +50,8 @@ final class CachingIterator implements Countable, Iterator
51
50
*/
52
51
public function __construct (Traversable $ iterator )
53
52
{
54
- $ this ->iterator = $ this ->wrapTraversable ($ iterator );
53
+ $ this ->iterator = new IteratorIterator ($ iterator );
54
+ $ this ->iterator ->rewind ();
55
55
$ this ->storeCurrentItem ();
56
56
}
57
57
@@ -94,9 +94,10 @@ public function key()
94
94
/** @see http://php.net/iterator.next */
95
95
public function next (): void
96
96
{
97
- if (! $ this ->iteratorExhausted ) {
98
- $ this ->getIterator () ->next ();
97
+ if ($ this ->iterator !== null ) {
98
+ $ this ->iterator ->next ();
99
99
$ this ->storeCurrentItem ();
100
+ $ this ->iteratorAdvanced = true ;
100
101
}
101
102
102
103
next ($ this ->items );
@@ -126,15 +127,13 @@ public function valid(): bool
126
127
*/
127
128
private function exhaustIterator (): void
128
129
{
129
- while (! $ this ->iteratorExhausted ) {
130
+ while ($ this ->iterator !== null ) {
130
131
$ this ->next ();
131
132
}
132
-
133
- $ this ->iterator = null ;
134
133
}
135
134
136
- /** @return Generator <mixed, TValue> */
137
- private function getIterator (): Generator
135
+ /** @return SPLIterator <mixed, TValue> */
136
+ private function getIterator (): SPLIterator
138
137
{
139
138
if ($ this ->iterator === null ) {
140
139
throw new RuntimeException ('Iterator has already been destroyed ' );
@@ -148,28 +147,12 @@ private function getIterator(): Generator
148
147
*/
149
148
private function storeCurrentItem (): void
150
149
{
151
- $ key = $ this ->getIterator () ->key ();
150
+ $ key = $ this ->iterator ->key ();
152
151
153
152
if ($ key === null ) {
154
- return ;
153
+ $ this ->iterator = null ;
154
+ } else {
155
+ $ this ->items [$ key ] = $ this ->getIterator ()->current ();
155
156
}
156
-
157
- $ this ->items [$ key ] = $ this ->getIterator ()->current ();
158
- }
159
-
160
- /**
161
- * @param Traversable<mixed, TValue> $traversable
162
- *
163
- * @return Generator<mixed, TValue>
164
- */
165
- private function wrapTraversable (Traversable $ traversable ): Generator
166
- {
167
- foreach ($ traversable as $ key => $ value ) {
168
- yield $ key => $ value ;
169
-
170
- $ this ->iteratorAdvanced = true ;
171
- }
172
-
173
- $ this ->iteratorExhausted = true ;
174
157
}
175
158
}
0 commit comments