Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
97.56% |
40 / 41 |
|
90.00% |
9 / 10 |
CRAP | |
0.00% |
0 / 1 |
Vector | |
97.56% |
40 / 41 |
|
90.00% |
9 / 10 |
21 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
create | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
2.02 | |||
empty | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
throwIfInvalidOffset | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
add | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
addRange | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
offsetExists | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
offsetGet | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
offsetSet | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
offsetUnset | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace PeServer\Core\Collection; |
6 | |
7 | use TypeError; |
8 | use PeServer\Core\Collection\Arr; |
9 | use PeServer\Core\Throws\ArgumentException; |
10 | use PeServer\Core\Throws\IndexOutOfRangeException; |
11 | use PeServer\Core\TypeUtility; |
12 | |
13 | /** |
14 | * 一次元配列。 |
15 | * |
16 | * @template TValue |
17 | * @phpstan-extends TypeArrayBase<non-negative-int,TValue> |
18 | */ |
19 | class Vector extends TypeArrayBase |
20 | { |
21 | /** |
22 | * 生成。 |
23 | * |
24 | * @param string $type |
25 | * @phpstan-param class-string|TypeUtility::TYPE_* $type |
26 | * @param array $items |
27 | * @phpstan-param array<array-key,TValue> $items |
28 | * @param bool $useValues |
29 | */ |
30 | public function __construct(string $type, ?array $items, bool $useValues) |
31 | { |
32 | parent::__construct($type); |
33 | |
34 | if (!Arr::isNullOrEmpty($items)) { |
35 | $this->addRange($items, $useValues); |
36 | } |
37 | } |
38 | |
39 | #region function |
40 | |
41 | /** |
42 | * 配列から生成。 |
43 | * |
44 | * @template TTValue |
45 | * @param array $items 配列。 |
46 | * @phpstan-param non-empty-array<TTValue> $items |
47 | * @param bool $useValues |
48 | * @return self |
49 | * @phpstan-return self<TTValue> |
50 | */ |
51 | public static function create(array $items, bool $useValues = true): self |
52 | { |
53 | if (Arr::isNullOrEmpty($items)) { |
54 | throw new ArgumentException('$items'); |
55 | } |
56 | |
57 | $firstKey = Arr::getFirstKey($items); |
58 | $firstValue = $items[$firstKey]; |
59 | |
60 | $type = TypeUtility::getType($firstValue); |
61 | return new self($type, $items, $useValues); |
62 | } |
63 | |
64 | /** |
65 | * 空データの生成。 |
66 | * |
67 | * @template TTValue |
68 | * @param string $type |
69 | * @phpstan-param class-string|TypeUtility::TYPE_* $type |
70 | * @return self |
71 | * @phpstan-return self<TTValue> |
72 | */ |
73 | public static function empty(string $type): self //@phpstan-ignore-line わかんね |
74 | { |
75 | return new self($type, [], false); |
76 | } |
77 | |
78 | protected function throwIfInvalidOffset(mixed $offset): void |
79 | { |
80 | if ($offset === null) { |
81 | throw new TypeError('$offset: null'); |
82 | } |
83 | |
84 | if (!is_int($offset)) { |
85 | throw new TypeError('$offset: ' . gettype($offset)); |
86 | } |
87 | } |
88 | |
89 | /** |
90 | * 追加。 |
91 | * |
92 | * @param mixed $value |
93 | * @phpstan-param TValue $value |
94 | * @return self |
95 | * @phpstan-return self<TValue> |
96 | */ |
97 | public function add(mixed $value): self |
98 | { |
99 | $this->isValidType($value); |
100 | |
101 | $this->items[] = $value; |
102 | |
103 | return $this; |
104 | } |
105 | |
106 | /** |
107 | * 追加。 |
108 | * |
109 | * @param array $items |
110 | * @phpstan-param array<array-key,TValue> $items |
111 | * @param bool $useValues |
112 | * @phpstan-return self<TValue> |
113 | */ |
114 | public function addRange(array $items, bool $useValues = true): self |
115 | { |
116 | if ($useValues) { |
117 | $items = Arr::getValues($items); |
118 | } elseif (!Arr::isList($items)) { |
119 | throw new ArgumentException('$items'); |
120 | } |
121 | |
122 | foreach ($items as $key => $value) { |
123 | $this->isValidType($value); |
124 | } |
125 | |
126 | /** @phpstan-var array<non-negative-int,TValue> $items */ |
127 | $this->items = array_merge($this->items, $items); |
128 | |
129 | return $this; |
130 | } |
131 | |
132 | #endregion |
133 | |
134 | #region TypeArrayBase |
135 | |
136 | /** |
137 | * @param int $offset |
138 | * @phpstan-param non-negative-int $offset |
139 | */ |
140 | public function offsetExists(mixed $offset): bool |
141 | { |
142 | $this->throwIfInvalidOffset($offset); |
143 | |
144 | return isset($this->items[$offset]); |
145 | } |
146 | /** |
147 | * @param int $offset |
148 | * @phpstan-param non-negative-int $offset |
149 | * @phpstan-return TValue $value |
150 | */ |
151 | public function offsetGet(mixed $offset): mixed |
152 | { |
153 | $this->throwIfInvalidOffset($offset); |
154 | |
155 | if (!isset($this->items[$offset])) { |
156 | throw new IndexOutOfRangeException('$offset: ' . $offset); |
157 | } |
158 | |
159 | return $this->items[$offset]; |
160 | } |
161 | /** |
162 | * @param int|null $offset |
163 | * @phpstan-param non-negative-int|null $offset |
164 | * @phpstan-param TValue $value |
165 | * @throws IndexOutOfRangeException |
166 | */ |
167 | public function offsetSet(mixed $offset, mixed $value): void |
168 | { |
169 | if ($offset === null) { |
170 | $this->add($value); |
171 | return; |
172 | } |
173 | |
174 | if (!isset($this->items[$offset])) { |
175 | throw new IndexOutOfRangeException('$offset: ' . $offset); |
176 | } |
177 | |
178 | $this->items[$offset] = $value; |
179 | } |
180 | /** |
181 | * @param int $offset |
182 | * @phpstan-param non-negative-int $offset |
183 | */ |
184 | public function offsetUnset(mixed $offset): void |
185 | { |
186 | $this->throwIfInvalidOffset($offset); |
187 | |
188 | if ($offset !== $this->count() - 1) { |
189 | throw new IndexOutOfRangeException('$offset: ' . $offset); |
190 | } |
191 | |
192 | unset($this->items[$offset]); |
193 | } |
194 | |
195 | #endregion |
196 | } |