Arrayed   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 31
eloc 66
dl 0
loc 251
rs 9.92
c 0
b 0
f 0

21 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A toArray() 0 3 1
A validIndex() 0 3 2
A last() 0 4 1
A first() 0 4 1
A setValues() 0 4 1
A clear() 0 4 1
A getValues() 0 3 1
A setSize() 0 3 1
A push() 0 3 1
A __clone() 0 3 1
A getSize() 0 3 1
A remove() 0 12 2
A pop() 0 11 1
A pushAll() 0 13 3
A insert() 0 10 3
A shift() 0 9 1
A set() 0 7 2
A get() 0 7 2
A normalizeRotations() 0 13 3
A unshift() 0 5 1
1
<?php namespace Mbh\Collection\Traits\Sequenceable;
2
3
use Mbh\Collection\Interfaces\Collection as CollectionInterface;
4
use Mbh\Collection\Interfaces\Sequenceable as SequenceableInterface;
5
use Mbh\Collection\FixedArray;
6
use Mbh\Collection\CallbackHeap;
7
use Mbh\Iterator\SliceIterator;
8
use Mbh\Iterator\ConcatIterator;
9
use Mbh\Collection\Traits\Builder;
10
use SplFixedArray;
11
use SplHeap;
12
use SplStack;
13
use LimitIterator;
14
use Iterator;
15
use ArrayAccess;
16
use Countable;
17
use CallbackFilterIterator;
18
use JsonSerializable;
19
use RuntimeException;
20
use Traversable;
21
use ReflectionClass;
22
use UnderflowException;
23
use OutOfRangeException;
24
25
/**
26
 * MBHFramework
27
 *
28
 * @link      https://github.com/MBHFramework/mbh-framework
29
 * @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos
30
 * @license   https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License)
31
 */
32
33
trait Arrayed
34
{
35
    use Arrayed\Countable;
36
    use Arrayed\ArrayAccess;
37
    use Arrayed\Iterator;
38
    use Builder;
39
40
    protected $sfa = null;
41
42
    /**
43
     * Create an fixed array
44
     *
45
     * @param Traversable $array data
46
     */
47
    protected function __construct(Traversable $array)
48
    {
49
        $this->sfa = $array;
50
    }
51
52
    /**
53
     * @inheritDoc
54
     */
55
    public function first()
56
    {
57
        $this->emptyGuard(__METHOD__);
58
        return $this[0];
59
    }
60
61
    /**
62
     * @inheritDoc
63
     */
64
    public function get(int $index)
65
    {
66
        if (!$this->validIndex($index)) {
67
            throw new OutOfRangeException();
68
        }
69
70
        return $this[$index];
71
    }
72
73
    /**
74
     * @inheritDoc
75
     */
76
    public function insert(int $index, ...$values)
77
    {
78
        if (!$this->validIndex($index) && $index !== $this->count()) {
79
            throw new OutOfRangeException();
80
        }
81
82
        $splice = $this->splice($index, 0, $values);
83
        $this->clear();
84
85
        $this->pushAll($splice);
86
    }
87
88
    /**
89
     * @inheritDoc
90
     */
91
    public function last()
92
    {
93
        $this->emptyGuard(__METHOD__);
94
        return $this[$this->count() - 1];
95
    }
96
97
    /**
98
     * Converts negative or large rotations into the minimum positive number
99
     * of rotations required to rotate the sequence by a given $r.
100
     */
101
    private function normalizeRotations(int $r)
102
    {
103
        $n = $this->count();
104
105
        if ($n < 2) {
106
            return 0;
107
        }
108
109
        if ($r < 0) {
110
            return $n - (abs($r) % $n);
111
        }
112
113
        return $r % $n;
114
    }
115
116
    /**
117
     * @inheritDoc
118
     */
119
    public function pop()
120
    {
121
        $this->emptyGuard(__METHOD__);
122
        $value = $this->last();
123
        $count = $this->count();
124
        unset($this[--$count]);
125
        $this->setSize($count);
126
127
        $this->checkCapacity();
128
129
        return $value;
130
    }
131
132
    /**
133
     * Pushes all values of either an array or traversable object.
134
     */
135
    private function pushAll(...$args)
136
    {
137
        $size = $this->getSize();
138
139
        foreach ($args as &$values) {
140
            $this->setSize($size + count($values));
141
142
            foreach ($values as $value) {
143
                $this[$size++] = $value;
144
            }
145
        }
146
147
        $this->checkCapacity();
148
    }
149
150
    /**
151
     * @inheritDoc
152
     */
153
    public function push(...$values)
154
    {
155
        $this->pushAll($values);
156
    }
157
158
    /**
159
     * @inheritDoc
160
     */
161
    public function remove(int $index)
162
    {
163
        if (!$this->validIndex($index)) {
164
            throw new OutOfRangeException();
165
        }
166
167
        $value = $this[$index];
168
        $splice = $this->splice($index + 1, 1, null);
169
        $this->clear();
170
171
        $this->pushAll($splice);
172
        return $value;
173
    }
174
175
    /**
176
     * @inheritDoc
177
     */
178
    public function set(int $index, $value)
179
    {
180
        if (!$this->validIndex($index)) {
181
            throw new OutOfRangeException();
182
        }
183
184
        $this->sfa->offsetSet($index, $value);
185
    }
186
187
    /**
188
     * @inheritDoc
189
     */
190
    public function shift()
191
    {
192
        $this->emptyGuard(__METHOD__);
193
        $value = $this->first();
194
        unset($this[0]);
195
196
        $this->checkCapacity();
197
198
        return $value;
199
    }
200
201
    /**
202
     * @inheritDoc
203
     */
204
    public function toArray(): array
205
    {
206
        return $this->sfa->toArray();
207
    }
208
209
    /**
210
     * @inheritDoc
211
     */
212
    public function unshift(...$values)
213
    {
214
        $this->insert(0, ...$values);
215
216
        return $this->count();
217
    }
218
219
    /**
220
     * @inheritDoc
221
     */
222
    protected function validIndex(int $index)
223
    {
224
        return $index >= 0 && $index < $this->count();
225
    }
226
227
    /**
228
     * @inheritDoc
229
     */
230
    public function clear()
231
    {
232
        $this->sfa->setSize(0);
233
        $this->capacity = self::MIN_CAPACITY;
0 ignored issues
show
Bug introduced by
The constant Mbh\Collection\Traits\Se...e\Arrayed::MIN_CAPACITY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug Best Practice introduced by
The property capacity does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
234
    }
235
236
    protected function getValues(): Traversable
237
    {
238
        return $this->sfa;
239
    }
240
241
    protected function setValues(Traversable $traversable)
242
    {
243
        $this->clear();
244
        $this->pushAll($traversable);
245
    }
246
247
    /**
248
     * Gets the size of the array.
249
     *
250
     * @return int
251
     */
252
    protected function getSize(): int
253
    {
254
        return $this->sfa->getSize();
255
    }
256
257
    /**
258
     * Change the size of an array to the new size of size.
259
     * If size is less than the current array size, any values after the
260
     * new size will be discarded. If size is greater than the current
261
     * array size, the array will be padded with NULL values.
262
     *
263
     * @param int $size The new array size. This should be a value between 0
264
     * and PHP_INT_MAX.
265
     * @return bool Returns TRUE on success or FALSE on failure.
266
     */
267
    protected function setSize(int $size): bool
268
    {
269
        return $this->sfa->setSize($size);
270
    }
271
272
    public function __clone()
273
    {
274
        $this->sfa = SplFixedArray::fromArray($this->toArray());
275
    }
276
277
    abstract protected function checkCapacity();
278
279
    abstract protected function emptyGuard($method);
280
281
    abstract public function isEmpty(): bool;
282
283
    abstract public function splice(int $begin = 0, int $length = null, $replacement = []);
284
}
285