1 /* 2 * Copyright (c) 2012-2018 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.bitmanip; 10 import std.conv; 11 import std.algorithm; 12 13 // Struct BitSet 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 if (i > fromIndex && el == true) 54 return to!int(i); 55 } 56 return -1; 57 } 58 59 public void set(int bitIndex, bool value) 60 { 61 if (bitSet.length <= bitIndex) 62 bitSet.length = bitIndex + 16; // dynamic array need more space 63 bitSet[bitIndex] = value; 64 } 65 66 /** 67 * @uml 68 * @nothrow 69 */ 70 public bool get(int bitIndex) nothrow 71 in 72 { 73 assert(bitSet.length > bitIndex); 74 } 75 do 76 { 77 return bitSet[bitIndex]; 78 } 79 80 public bool isEmpty() 81 { 82 return cardinality == 0; 83 } 84 85 public string toString() 86 { 87 import std.format : format; 88 return format("%b", bitSet); 89 } 90 91 /** 92 * @uml 93 * @trusted 94 */ 95 public size_t toHash() @trusted 96 { 97 size_t hash; 98 foreach (el; bitSet) 99 hash = (hash * 9) + el; 100 return hash; 101 } 102 103 /** 104 * @uml 105 * @const 106 * @pure 107 * @nothrow 108 */ 109 public bool opEquals(ref const BitSet bitSet) const pure nothrow 110 { 111 return this.bitSet == bitSet.bitSet; 112 } 113 114 public void clear() 115 { 116 bitSet.length(0); 117 } 118 119 public BitSet or(BitSet bits) 120 { 121 BitSet result; 122 auto maxLenght = max(this.bitSet.length, bits.bitSet.length); 123 if (this.bitSet.length < maxLenght) 124 this.bitSet.length = maxLenght; 125 else 126 if (bits.values.length < maxLenght) 127 bits.values.length = maxLenght; 128 result.bitSet = this.bitSet | bits.bitSet; 129 return result; 130 } 131 132 public string toIndexString() 133 { 134 import std.conv; 135 import std.array : join; 136 string[] res; 137 int index; 138 foreach(i, el; bitSet) 139 { 140 if(el) 141 res ~= to!string(i); 142 } 143 return "{" ~ join(res, ",") ~ "}"; 144 } 145 146 public BitArray values() 147 { 148 return bitSet; 149 } 150 151 public void dup(BitSet old) 152 { 153 this.bitSet = old.bitSet.dup; 154 } 155 156 }