Sequence::offsetExists()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 14
ccs 8
cts 8
cp 1
rs 10
cc 4
nc 4
nop 1
crap 4
1
<?php
2
3
namespace Smoren\Sequence\Structs;
4
5
use Smoren\Sequence\Exceptions\OutOfRangeException;
6
use Smoren\Sequence\Exceptions\ReadOnlyException;
7
use Smoren\Sequence\Interfaces\SequenceInterface;
8
use Smoren\Sequence\Interfaces\SequenceIteratorInterface;
9
use Smoren\Sequence\Iterators\SequenceIterator;
10
11
/**
12
 * Base class for sequences.
13
 *
14
 * @template T
15
 * @implements SequenceInterface<T>
16
 */
17
abstract class Sequence implements SequenceInterface
18
{
19
    /**
20
     * @var T start value of the sequence
0 ignored issues
show
Bug introduced by
The type Smoren\Sequence\Structs\T was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
     */
22
    protected $start;
23
    /**
24
     * @var int<0, max>|null size of the sequence (infinite if null)
25
     */
26
    protected ?int $size;
27
28
    /**
29
     * Sequence constructor.
30
     *
31
     * @param T $start
32
     * @param int<0, max>|null $size
33
     */
34 105
    public function __construct($start, ?int $size)
35
    {
36 105
        $this->start = $start;
37 105
        $this->size = $size;
38
    }
39
40
    /**
41
     * {@inheritDoc}
42
     */
43 90
    public function offsetExists($offset): bool
44
    {
45 90
        if (!is_int($offset)) {
46 4
            return false;
47
        }
48
49 88
        if (!$this->isInfinite()) {
50 70
            if ($offset >= 0) {
51 70
                return $offset < count($this);
52
            }
53 70
            return abs($offset) <= count($this);
54
        }
55
56 18
        return true;
57
    }
58
59
    /**
60
     * {@inheritDoc}
61
     */
62 37
    public function offsetSet($offset, $value): void
63
    {
64 37
        throw new ReadOnlyException();
65
    }
66
67
    /**
68
     * {@inheritDoc}
69
     */
70 2
    public function offsetUnset($offset): void
71
    {
72 2
        throw new ReadOnlyException();
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     */
78 85
    public function count(): int
79
    {
80 85
        return $this->size ?? -1;
81
    }
82
83
    /**
84
     * {@inheritDoc}
85
     */
86 103
    public function isInfinite(): bool
87
    {
88 103
        return $this->size === null;
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     */
94 70
    public function getStartValue()
95
    {
96 70
        return $this->getValueByIndex(0);
97
    }
98
99
    /**
100
     * {@inheritDoc}
101
     */
102 90
    public function offsetGet($offset)
103
    {
104 90
        if (!$this->offsetExists($offset)) {
105 35
            throw new OutOfRangeException();
106
        }
107
108
        /** @var int $offset */
109
110 58
        if ($this->isInfinite()) {
111 18
            return $this->getValueByIndex($offset);
112
        }
113
114 40
        if ($offset < 0) {
115 40
            $offset = $this->size + ($offset % $this->size);
116
        }
117
118 40
        $offset = ($offset % $this->size);
119
120 40
        return $this->getValueByIndex($offset);
121
    }
122
123
    /**
124
     * {@inheritDoc}
125
     */
126 70
    public function getIterator(): SequenceIteratorInterface
127
    {
128 70
        return new SequenceIterator($this);
129
    }
130
}
131