Passed
Push — 1.x ( 2f6c1b...f64955 )
by Ulises Jeremias
02:44
created

Arrayed::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 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 SplFixedArray;
10
use SplHeap;
11
use SplStack;
12
use LimitIterator;
13
use Iterator;
14
use ArrayAccess;
15
use Countable;
16
use CallbackFilterIterator;
17
use JsonSerializable;
18
use RuntimeException;
19
use Traversable;
20
use ReflectionClass;
21
use UnderflowException;
22
use OutOfRangeException;
23
24
/**
25
 * MBHFramework
26
 *
27
 * @link      https://github.com/MBHFramework/mbh-framework
28
 * @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos
29
 * @license   https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License)
30
 */
31
32
trait Arrayed
33
{
34
    use Arrayed\Countable;
35
    use Arrayed\ArrayAccess;
36
    use Arrayed\Iterator;
37
    use Arrayed\Builder;
38
39
    protected $sfa = null;
40
41
    /**
42
     * Create an fixed array
43
     *
44
     * @param Traversable $array data
45
     */
46
    protected function __construct(Traversable $array)
47
    {
48
        $this->sfa = $array;
49
        $this->checkCapacity();
50
    }
51
52
    /**
53
     * @inheritDoc
54
     */
55
    public function contains(...$values): bool
56
    {
57
        foreach ($values as $value) {
58
            if ($this->search($value) !== null) {
59
                return false;
60
            }
61
        }
62
63
        return true;
64
    }
65
66
    /**
67
     * @inheritDoc
68
     */
69
    public function copy()
70
    {
71
        return static::fromArray($this->toArray());
72
    }
73
74
    /**
75
     * @inheritDoc
76
     */
77
    public function first()
78
    {
79
        $this->emptyGuard(__METHOD__);
80
        return $this[0];
81
    }
82
83
    /**
84
     * @inheritDoc
85
     */
86
    public function get(int $index)
87
    {
88
        if (!$this->validIndex($index)) {
89
            throw new OutOfRangeException();
90
        }
91
92
        return $this[$index];
93
    }
94
95
    /**
96
     * @inheritDoc
97
     */
98
    public function insert(int $index, ...$values)
99
    {
100
        if (!$this->validIndex($index) && $index !== $this->count()) {
101
            throw new OutOfRangeException();
102
        }
103
104
        $splice = $this->splice($index, 0, $values);
105
        $this->clear();
106
107
        $this->pushAll($splice);
108
    }
109
110
    /**
111
     * @inheritDoc
112
     */
113
    public function last()
114
    {
115
        $this->emptyGuard(__METHOD__);
116
        return $this[$this->count() - 1];
117
    }
118
119
    /**
120
     * Converts negative or large rotations into the minimum positive number
121
     * of rotations required to rotate the sequence by a given $r.
122
     */
123
    private function normalizeRotations(int $r)
124
    {
125
        $n = $this->count();
126
127
        if ($n < 2) {
128
            return 0;
129
        }
130
131
        if ($r < 0) {
132
            return $n - (abs($r) % $n);
133
        }
134
135
        return $r % $n;
136
    }
137
138
    /**
139
     * @inheritDoc
140
     */
141
    public function pop()
142
    {
143
        $this->emptyGuard(__METHOD__);
144
        $value = $this->last();
145
        $count = $this->count();
146
        unset($this[--$count]);
147
        $this->setSize($count);
148
149
        $this->checkCapacity();
150
151
        return $value;
152
    }
153
154
    /**
155
     * Pushes all values of either an array or traversable object.
156
     */
157
    private function pushAll(...$args)
158
    {
159
        $size = $this->getSize();
160
161
        foreach ($args as &$values) {
162
            $this->setSize($size + count($values));
163
164
            foreach ($values as $value) {
165
                $this[$size++] = $value;
166
            }
167
        }
168
169
        $this->checkCapacity();
170
    }
171
172
    /**
173
     * @inheritDoc
174
     */
175
    public function push(...$values)
176
    {
177
        $this->pushAll($values);
178
    }
179
180
    /**
181
     * @inheritDoc
182
     */
183
    public function remove(int $index)
184
    {
185
        if (!$this->validIndex($index)) {
186
            throw new OutOfRangeException();
187
        }
188
189
        $value = $this[$index];
190
        $splice = $this->splice($index + 1, 1, null);
191
        $this->clear();
192
193
        $this->pushAll($splice);
194
        return $value;
195
    }
196
197
    /**
198
     * @inheritDoc
199
     */
200
    public function set(int $index, $value)
201
    {
202
        if (!$this->validIndex($index)) {
203
            throw new OutOfRangeException();
204
        }
205
206
        $this->sfa->offsetSet($index, $value);
207
    }
208
209
    /**
210
     * @inheritDoc
211
     */
212
    public function shift()
213
    {
214
        $this->emptyGuard(__METHOD__);
215
        $value = $this->first();
216
        unset($this[0]);
217
218
        $this->checkCapacity();
219
220
        return $value;
221
    }
222
223
    /**
224
     * @inheritDoc
225
     */
226
    public function toArray(): array
227
    {
228
        return $this->sfa->toArray();
229
    }
230
231
    /**
232
     * @inheritDoc
233
     */
234
    public function unshift(...$values)
235
    {
236
        $this->insert(0, ...$values);
237
238
        return $this->count();
239
    }
240
241
    /**
242
     * @inheritDoc
243
     */
244
    public function unserialize($values)
245
    {
246
        $values = unserialize($values);
247
        $this->setSfa(SplFixedArray::fromArray($values));
248
    }
249
250
    /**
251
     * @inheritDoc
252
     */
253
    protected function validIndex(int $index)
254
    {
255
        return $index >= 0 && $index < $this->getSize();
256
    }
257
258
    /**
259
     * @inheritDoc
260
     */
261
    public function clear()
262
    {
263
        $this->sfa->setSize(0);
264
        $this->checkCapacity();
265
    }
266
267
    protected function getSfa(): Traversable
268
    {
269
        return $this->sfa;
270
    }
271
272
    protected function setSfa(Traversable $traversable)
273
    {
274
        $this->sfa = $traversable;
275
    }
276
277
    /**
278
     * Gets the size of the array.
279
     *
280
     * @return int
281
     */
282
    protected function getSize(): int
283
    {
284
        return $this->sfa->getSize();
285
    }
286
287
    /**
288
     * Change the size of an array to the new size of size.
289
     * If size is less than the current array size, any values after the
290
     * new size will be discarded. If size is greater than the current
291
     * array size, the array will be padded with NULL values.
292
     *
293
     * @param int $size The new array size. This should be a value between 0
294
     * and PHP_INT_MAX.
295
     * @return bool Returns TRUE on success or FALSE on failure.
296
     */
297
    protected function setSize(int $size): bool
298
    {
299
        return $this->sfa->setSize($size);
300
    }
301
302
    public function __clone()
303
    {
304
        return $this->copy();
305
    }
306
307
    abstract protected function checkCapacity();
308
309
    abstract protected function emptyGuard($method);
310
311
    abstract public function isEmpty(): bool;
312
313
    abstract public function search($value);
314
315
    abstract public function splice(int $begin = 0, int $length = null, $replacement = []);
316
}
317