Completed
Push — master ( 88ff28...2dc58f )
by Kirill
06:03
created

SlicedIterator   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 0
dl 0
loc 120
ccs 0
cts 55
cp 0
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A toArray() 0 4 2
A getOuterIterator() 0 8 2
A lookahead() 0 4 1
A slice() 0 8 1
A sliceWhile() 0 10 3
A current() 0 4 1
A next() 0 4 1
A key() 0 4 1
A valid() 0 5 2
A rewind() 0 4 1
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\Compiler\Iterator;
11
12
/**
13
 * Class SlicedIterator
14
 */
15
class SlicedIterator implements \Iterator
16
{
17
    /**
18
     * @var array
19
     */
20
    private $iterator;
21
22
    /**
23
     * @var int
24
     */
25
    private $cursor = 0;
26
27
    /**
28
     * SlicedIterator constructor.
29
     * @param iterable $iterator
30
     */
31
    public function __construct(iterable $iterator)
32
    {
33
        $this->iterator = \array_values($this->toArray($iterator));
34
    }
35
36
    /**
37
     * @param iterable $iterator
38
     * @return array
39
     */
40
    private function toArray(iterable $iterator): array
41
    {
42
        return $iterator instanceof \Traversable ? \iterator_to_array($iterator) : $iterator;
43
    }
44
45
    /**
46
     * @return \Traversable
47
     */
48
    public function getOuterIterator(): \Traversable
49
    {
50
        $cursor = $this->cursor;
51
52
        for ($i = 0; \array_key_exists($cursor, $this->iterator); ++$i) {
53
            yield $i => $this->iterator[$cursor++];
54
        }
55
    }
56
57
    /**
58
     * @param int $offset
59
     * @return mixed|null
60
     */
61
    public function lookahead(int $offset = 0)
62
    {
63
        return $this->iterator[$this->cursor + $offset] ?? null;
64
    }
65
66
    /**
67
     * @param int $offset
68
     * @return \Traversable|SlicedIterator
69
     */
70
    public function slice(int $offset): \Traversable
71
    {
72
        $result = \array_splice($this->iterator, $this->cursor, $offset);
73
74
        $this->iterator = \array_values($this->iterator);
75
76
        return new static($result);
0 ignored issues
show
Documentation introduced by
$result is of type array, but the function expects a object<Railt\Compiler\Iterator\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
77
    }
78
79
    /**
80
     * @param \Closure $filter
81
     * @return \Traversable|SlicedIterator
82
     */
83
    public function sliceWhile(\Closure $filter): \Traversable
84
    {
85
        foreach ($this->getOuterIterator() as $i => $item) {
86
            if ($filter($item)) {
87
                return $this->slice($i);
88
            }
89
        }
90
91
        return new static([]);
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a object<Railt\Compiler\Iterator\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
    }
93
94
    /**
95
     * @return mixed|null
96
     */
97
    public function current()
98
    {
99
        return $this->iterator[$this->cursor] ?? null;
100
    }
101
102
    /**
103
     * @return void
104
     */
105
    public function next(): void
106
    {
107
        $this->cursor++;
108
    }
109
110
    /**
111
     * @return int
112
     */
113
    public function key(): int
114
    {
115
        return $this->cursor;
116
    }
117
118
    /**
119
     * @return bool
120
     */
121
    public function valid(): bool
122
    {
123
        return isset($this->iterator[$this->cursor]) &&
124
            \array_key_exists($this->cursor, $this->iterator);
125
    }
126
127
    /**
128
     * @return void
129
     */
130
    public function rewind(): void
131
    {
132
        $this->cursor = 0;
133
    }
134
}
135