Passed
Push — 1.x ( 3a457a...b78ae7 )
by Ulises Jeremias
02:31
created

SliceIterator::clear()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php namespace Mbh\Iterator;
2
3
/**
4
 * MBHFramework
5
 *
6
 * @link      https://github.com/MBHFramework/mbh-framework
7
 * @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos
8
 * @license   https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License)
9
 */
10
11
use ArrayAccess;
12
use LimitIterator;
13
use JsonSerializable;
14
use Countable;
15
use Iterator;
16
use InvalidArgumentException;
17
use RuntimeException;
18
19
/**
20
* Iterator to allow a slice to be used like an array
21
*/
22
23
class SliceIterator extends LimitIterator implements Countable, Iterator
24
{
25
    protected $count = 0;
26
    protected $begin = 0;
27
28
    const INVALID_INDEX = 'Index invalid or out of range';
29
30
    /**
31
     * Build an iterator over a slice of an ArrayAccess object
32
     * Unlike a LimitIterator, the $end defines the last index, not the count
33
     *
34
     * @param Iterator $iterator An ArrayAccess iterator, e.g. SplFixedArray
35
     * @param int $begin The starting offset of the slice
36
     * @param int $end The last index of the slice
37
     */
38
    public function __construct(Iterator $iterator, $begin = 0, $end = null)
39
    {
40
        if ($iterator instanceof ArrayAccess && $iterator instanceof Countable) {
41
            $count = count($iterator);
42
43
            // Negative begin means start from the end
44
            if ($begin < 0) {
45
                $begin = max(0, $count + $begin);
46
            }
47
48
            // If no end set, assume whole array
49
            if ($end === null) {
50
                $end = $count;
51
            } elseif ($end < 0) {
52
                // Ends counting back from start
53
                $end = max($begin, $count + $end);
54
            }
55
56
            // Set the size of iterable object, for quick-lookup
57
            $this->count = max(0, $end - $begin);
58
59
            // Need to store the starting offset to adjust by
60
            $this->begin = $begin;
61
62
            // Init as LimitIterator
63
            parent::__construct($iterator, $this->begin, $this->count);
64
        } else {
65
            throw new InvalidArgumentException('Iterator must be a Countable ArrayAccess');
66
        }
67
    }
68
69
    /**
70
     * Rewind, extended for clean results on empty sets
71
     */
72
    public function rewind()
73
    {
74
        // no need to rewind on empty sets
75
        if ($this->count > 0) {
76
            parent::rewind();
77
        }
78
    }
79
80
    /**
81
     * Countable
82
     */
83
    public function count(): int
84
    {
85
        return $this->count;
86
    }
87
88
    public function toArray(): array
89
    {
90
        return iterator_to_array($this, false);
91
    }
92
}
93