1 /* 2 * Copyright (c) 2012-2020 The ANTLR Project. All rights reserved. 3 * Use of this file is governed by the BSD 3-clause license that 4 * can be found in the LICENSE.txt file in the project root. 5 */ 6 7 module antlr.v4.runtime.misc.BitSet; 8 9 import std.algorithm; 10 import std.bitmanip; 11 import std.conv; 12 import std.format : format; 13 14 /** 15 * This struct implements a vector of bits that grows as needed. Each component 16 * of the bit set has a bool value. The bits of a BitSet are indexed by nonnegative integers. 17 * Individual indexed bits can be examined, set, or cleared. One BitSet may be used to modify 18 * the contents of another BitSet through logical AND, logical inclusive OR, 19 * and logical exclusive OR operations. 20 * 21 * By default, all bits in the set initially have the value false. 22 */ 23 struct BitSet 24 { 25 26 private BitArray bitSet; 27 28 public this(BitArray bitArray) 29 { 30 this.bitSet = bitArray; 31 } 32 33 public this(size_t initialSize) 34 { 35 this.bitSet.length = initialSize; 36 } 37 38 public size_t length() 39 { 40 return bitSet.length; 41 } 42 43 public auto cardinality() 44 { 45 int res; 46 bitSet.each!(v => res += to!int(v)); 47 return res; 48 } 49 50 public int nextSetBit(int fromIndex) 51 { 52 foreach (i, el; bitSet) 53 { 54 if (i > fromIndex && el == true) 55 return to!int(i); 56 } 57 return -1; 58 } 59 60 public void set(int bitIndex, bool value) 61 { 62 if (bitSet.length <= bitIndex) 63 bitSet.length = bitIndex + 16; // dynamic array need more space 64 bitSet[bitIndex] = value; 65 } 66 67 /** 68 * @uml 69 * @nothrow 70 */ 71 public bool get(int bitIndex) nothrow 72 in 73 { 74 assert(bitSet.length > bitIndex); 75 } 76 do 77 { 78 return bitSet[bitIndex]; 79 } 80 81 public bool isEmpty() 82 { 83 return cardinality == 0; 84 } 85 86 public string toString() 87 { 88 if (bitSet.length) 89 { 90 string res; 91 foreach (j, b; bitSet) 92 { 93 if (b == true) 94 { 95 res ~= to!string(j) ~ ", "; 96 } 97 } 98 return format!"{%s}"(res[0 .. $ - 2]); 99 } 100 else 101 return "{}"; 102 } 103 104 /** 105 * @uml 106 * @trusted 107 */ 108 public size_t toHash() @trusted 109 { 110 size_t hash; 111 foreach (el; bitSet) 112 hash = (hash * 9) + el; 113 return hash; 114 } 115 116 /** 117 * @uml 118 * @const 119 * @pure 120 * @nothrow 121 */ 122 public bool opEquals(ref const BitSet bitSet) const pure nothrow 123 { 124 return this.bitSet == bitSet.bitSet; 125 } 126 127 public void clear() 128 { 129 bitSet.length(0); 130 } 131 132 public BitSet or(BitSet bits) 133 { 134 BitSet result; 135 auto maxLenght = max(this.bitSet.length, bits.bitSet.length); 136 if (this.bitSet.length < maxLenght) 137 this.bitSet.length = maxLenght; 138 else if (bits.values.length < maxLenght) 139 bits.values.length = maxLenght; 140 result.bitSet = this.bitSet | bits.bitSet; 141 return result; 142 } 143 144 public string toIndexString() 145 { 146 import std.conv; 147 import std.array : join; 148 149 string[] res; 150 int index; 151 foreach (i, el; bitSet) 152 { 153 if (el) 154 res ~= to!string(i); 155 } 156 return "{" ~ join(res, ",") ~ "}"; 157 } 158 159 public BitArray values() 160 { 161 return bitSet; 162 } 163 164 public void dup(BitSet old) 165 { 166 this.bitSet = old.bitSet.dup; 167 } 168 169 }