Passed
Push — master ( 77aa03...453f7d )
by Nikita
02:16
created

ArrayBitSet::or()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 1
1
<?php
2
/**
3
 * This file is part of PHP-Yacc package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace PhpYacc\Lalr;
11
12
/**
13
 * Class ArrayBitset.
14
 */
15
class ArrayBitSet implements BitSet
16
{
17
    const BITS = \PHP_INT_SIZE * 8;
18
19
    /**
20
     * @var int
21
     */
22
    public $numBits;
23
24
    /**
25
     * @var array
26
     */
27
    public $array;
28
29
    /**
30
     * ArrayBitset constructor.
31
     *
32
     * @param int $numBits
33
     */
34
    public function __construct(int $numBits)
35
    {
36
        $this->numBits = $numBits;
37
        $this->array = \array_fill(0, intdiv($numBits + self::BITS - 1, self::BITS), 0);
38
    }
39
40
    /**
41
     * @return void
42
     */
43
    public function __clone()
44
    {
45
        $this->array = \array_values($this->array);
46
    }
47
48
    /**
49
     * @param int $i
50
     *
51
     * @return bool
52
     */
53
    public function testBit(int $i): bool
54
    {
55
        return ($this->array[$i / self::BITS] & (1 << ($i % self::BITS))) !== 0;
56
    }
57
58
    /**
59
     * @param int $i
60
     */
61
    public function setBit(int $i)
62
    {
63
        $this->array[$i / self::BITS] |= (1 << ($i % self::BITS));
64
    }
65
66
    /**
67
     * @param int $i
68
     */
69
    public function clearBit(int $i)
70
    {
71
        $this->array[$i / self::BITS] &= ~(1 << ($i % self::BITS));
72
    }
73
74
    /**
75
     * @param BitSet $other
76
     *
77
     * @return bool
78
     */
79
    public function or(BitSet $other): bool
80
    {
81
        /* @var $other ArrayBitSet */
82
        assert($this->numBits === $other->numBits);
83
84
        $changed = false;
85
        foreach ($this->array as $key => $value) {
86
            $this->array[$key] = $value | $other->array[$key];
87
            $changed = $changed || $value !== $this->array[$key];
88
        }
89
90
        return $changed;
91
    }
92
93
    /**
94
     * @return \Generator
95
     */
96
    public function getIterator(): \Generator
97
    {
98
        $count = \count($this->array);
99
        for ($n = 0; $n < $count; $n++) {
100
            $elem = $this->array[$n];
101
            if ($elem !== 0) {
102
                for ($i = 0; $i < self::BITS; $i++) {
103
                    if ($elem & (1 << $i)) {
104
                        yield $n * self::BITS + $i;
105
                    }
106
                }
107
            }
108
        }
109
    }
110
}
111