PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Dependencies/boo/lib/antlr-2.7.5/antlr/collections/impl/BitSet.java

https://github.com/w4x/boolangstudio
Java | 483 lines | 341 code | 48 blank | 94 comment | 84 complexity | c9f9debc45c1a5c31ddd3bfa318a6b60 MD5 | raw file
Possible License(s): GPL-2.0
  1. package antlr.collections.impl;
  2. /* ANTLR Translator Generator
  3. * Project led by Terence Parr at http://www.jGuru.com
  4. * Software rights: http://www.antlr.org/license.html
  5. *
  6. * $Id: //depot/code/org.antlr/release/antlr-2.7.5/antlr/collections/impl/BitSet.java#1 $
  7. */
  8. import antlr.CharFormatter;
  9. /**A BitSet to replace java.util.BitSet.
  10. * Primary differences are that most set operators return new sets
  11. * as opposed to oring and anding "in place". Further, a number of
  12. * operations were added. I cannot contain a BitSet because there
  13. * is no way to access the internal bits (which I need for speed)
  14. * and, because it is final, I cannot subclass to add functionality.
  15. * Consider defining set degree. Without access to the bits, I must
  16. * call a method n times to test the ith bit...ack!
  17. *
  18. * Also seems like or() from util is wrong when size of incoming set is bigger
  19. * than this.bits.length.
  20. *
  21. * @author Terence Parr
  22. * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
  23. */
  24. public class BitSet implements Cloneable {
  25. protected final static int BITS = 64; // number of bits / long
  26. protected final static int NIBBLE = 4;
  27. protected final static int LOG_BITS = 6; // 2^6 == 64
  28. /* We will often need to do a mod operator (i mod nbits). Its
  29. * turns out that, for powers of two, this mod operation is
  30. * same as (i & (nbits-1)). Since mod is slow, we use a
  31. * precomputed mod mask to do the mod instead.
  32. */
  33. protected final static int MOD_MASK = BITS - 1;
  34. /** The actual data bits */
  35. protected long bits[];
  36. /** Construct a bitset of size one word (64 bits) */
  37. public BitSet() {
  38. this(BITS);
  39. }
  40. /** Construction from a static array of longs */
  41. public BitSet(long[] bits_) {
  42. bits = bits_;
  43. }
  44. /** Construct a bitset given the size
  45. * @param nbits The size of the bitset in bits
  46. */
  47. public BitSet(int nbits) {
  48. bits = new long[((nbits - 1) >> LOG_BITS) + 1];
  49. }
  50. /** or this element into this set (grow as necessary to accommodate) */
  51. public void add(int el) {
  52. //System.out.println("add("+el+")");
  53. int n = wordNumber(el);
  54. //System.out.println("word number is "+n);
  55. //System.out.println("bits.length "+bits.length);
  56. if (n >= bits.length) {
  57. growToInclude(el);
  58. }
  59. bits[n] |= bitMask(el);
  60. }
  61. public BitSet and(BitSet a) {
  62. BitSet s = (BitSet)this.clone();
  63. s.andInPlace(a);
  64. return s;
  65. }
  66. public void andInPlace(BitSet a) {
  67. int min = Math.min(bits.length, a.bits.length);
  68. for (int i = min - 1; i >= 0; i--) {
  69. bits[i] &= a.bits[i];
  70. }
  71. // clear all bits in this not present in a (if this bigger than a).
  72. for (int i = min; i < bits.length; i++) {
  73. bits[i] = 0;
  74. }
  75. }
  76. private final static long bitMask(int bitNumber) {
  77. int bitPosition = bitNumber & MOD_MASK; // bitNumber mod BITS
  78. return 1L << bitPosition;
  79. }
  80. public void clear() {
  81. for (int i = bits.length - 1; i >= 0; i--) {
  82. bits[i] = 0;
  83. }
  84. }
  85. public void clear(int el) {
  86. int n = wordNumber(el);
  87. if (n >= bits.length) { // grow as necessary to accommodate
  88. growToInclude(el);
  89. }
  90. bits[n] &= ~bitMask(el);
  91. }
  92. public Object clone() {
  93. BitSet s;
  94. try {
  95. s = (BitSet)super.clone();
  96. s.bits = new long[bits.length];
  97. System.arraycopy(bits, 0, s.bits, 0, bits.length);
  98. }
  99. catch (CloneNotSupportedException e) {
  100. throw new InternalError();
  101. }
  102. return s;
  103. }
  104. public int degree() {
  105. int deg = 0;
  106. for (int i = bits.length - 1; i >= 0; i--) {
  107. long word = bits[i];
  108. if (word != 0L) {
  109. for (int bit = BITS - 1; bit >= 0; bit--) {
  110. if ((word & (1L << bit)) != 0) {
  111. deg++;
  112. }
  113. }
  114. }
  115. }
  116. return deg;
  117. }
  118. /** code "inherited" from java.util.BitSet */
  119. public boolean equals(Object obj) {
  120. if ((obj != null) && (obj instanceof BitSet)) {
  121. BitSet set = (BitSet)obj;
  122. int n = Math.min(bits.length, set.bits.length);
  123. for (int i = n; i-- > 0;) {
  124. if (bits[i] != set.bits[i]) {
  125. return false;
  126. }
  127. }
  128. if (bits.length > n) {
  129. for (int i = bits.length; i-- > n;) {
  130. if (bits[i] != 0) {
  131. return false;
  132. }
  133. }
  134. }
  135. else if (set.bits.length > n) {
  136. for (int i = set.bits.length; i-- > n;) {
  137. if (set.bits[i] != 0) {
  138. return false;
  139. }
  140. }
  141. }
  142. return true;
  143. }
  144. return false;
  145. }
  146. /** Find ranges in a set element array. @param elems The array of
  147. * elements representing the set, usually from Bit Set.toArray().
  148. * @return Vector of ranges.
  149. */
  150. public static Vector getRanges(int[] elems) {
  151. if (elems.length == 0) {
  152. return null;
  153. }
  154. int begin = elems[0];
  155. int end = elems[elems.length - 1];
  156. if (elems.length <= 2) {
  157. // Not enough elements for a range expression
  158. return null;
  159. }
  160. Vector ranges = new Vector(5);
  161. // look for ranges
  162. for (int i = 0; i < elems.length - 2; i++) {
  163. int lastInRange;
  164. lastInRange = elems.length - 1;
  165. for (int j = i + 1; j < elems.length; j++) {
  166. if (elems[j] != elems[j - 1] + 1) {
  167. lastInRange = j - 1;
  168. break;
  169. }
  170. }
  171. // found a range
  172. if (lastInRange - i > 2) {
  173. ranges.appendElement(new IntRange(elems[i], elems[lastInRange]));
  174. }
  175. }
  176. return ranges;
  177. }
  178. /**
  179. * Grows the set to a larger number of bits.
  180. * @param bit element that must fit in set
  181. */
  182. public void growToInclude(int bit) {
  183. int newSize = Math.max(bits.length << 1, numWordsToHold(bit));
  184. long newbits[] = new long[newSize];
  185. System.arraycopy(bits, 0, newbits, 0, bits.length);
  186. bits = newbits;
  187. }
  188. public boolean member(int el) {
  189. int n = wordNumber(el);
  190. if (n >= bits.length) return false;
  191. return (bits[n] & bitMask(el)) != 0;
  192. }
  193. public boolean nil() {
  194. for (int i = bits.length - 1; i >= 0; i--) {
  195. if (bits[i] != 0) return false;
  196. }
  197. return true;
  198. }
  199. public BitSet not() {
  200. BitSet s = (BitSet)this.clone();
  201. s.notInPlace();
  202. return s;
  203. }
  204. public void notInPlace() {
  205. for (int i = bits.length - 1; i >= 0; i--) {
  206. bits[i] = ~bits[i];
  207. }
  208. }
  209. /** complement bits in the range 0..maxBit. */
  210. public void notInPlace(int maxBit) {
  211. notInPlace(0, maxBit);
  212. }
  213. /** complement bits in the range minBit..maxBit.*/
  214. public void notInPlace(int minBit, int maxBit) {
  215. // make sure that we have room for maxBit
  216. growToInclude(maxBit);
  217. for (int i = minBit; i <= maxBit; i++) {
  218. int n = wordNumber(i);
  219. bits[n] ^= bitMask(i);
  220. }
  221. }
  222. private final int numWordsToHold(int el) {
  223. return (el >> LOG_BITS) + 1;
  224. }
  225. public static BitSet of(int el) {
  226. BitSet s = new BitSet(el + 1);
  227. s.add(el);
  228. return s;
  229. }
  230. /** return this | a in a new set */
  231. public BitSet or(BitSet a) {
  232. BitSet s = (BitSet)this.clone();
  233. s.orInPlace(a);
  234. return s;
  235. }
  236. public void orInPlace(BitSet a) {
  237. // If this is smaller than a, grow this first
  238. if (a.bits.length > bits.length) {
  239. setSize(a.bits.length);
  240. }
  241. int min = Math.min(bits.length, a.bits.length);
  242. for (int i = min - 1; i >= 0; i--) {
  243. bits[i] |= a.bits[i];
  244. }
  245. }
  246. // remove this element from this set
  247. public void remove(int el) {
  248. int n = wordNumber(el);
  249. if (n >= bits.length) {
  250. growToInclude(el);
  251. }
  252. bits[n] &= ~bitMask(el);
  253. }
  254. /**
  255. * Sets the size of a set.
  256. * @param nwords how many words the new set should be
  257. */
  258. private void setSize(int nwords) {
  259. long newbits[] = new long[nwords];
  260. int n = Math.min(nwords, bits.length);
  261. System.arraycopy(bits, 0, newbits, 0, n);
  262. bits = newbits;
  263. }
  264. public int size() {
  265. return bits.length << LOG_BITS; // num words * bits per word
  266. }
  267. /** return how much space is being used by the bits array not
  268. * how many actually have member bits on.
  269. */
  270. public int lengthInLongWords() {
  271. return bits.length;
  272. }
  273. /**Is this contained within a? */
  274. public boolean subset(BitSet a) {
  275. if (a == null || !(a instanceof BitSet)) return false;
  276. return this.and(a).equals(this);
  277. }
  278. /**Subtract the elements of 'a' from 'this' in-place.
  279. * Basically, just turn off all bits of 'this' that are in 'a'.
  280. */
  281. public void subtractInPlace(BitSet a) {
  282. if (a == null) return;
  283. // for all words of 'a', turn off corresponding bits of 'this'
  284. for (int i = 0; i < bits.length && i < a.bits.length; i++) {
  285. bits[i] &= ~a.bits[i];
  286. }
  287. }
  288. public int[] toArray() {
  289. int[] elems = new int[degree()];
  290. int en = 0;
  291. for (int i = 0; i < (bits.length << LOG_BITS); i++) {
  292. if (member(i)) {
  293. elems[en++] = i;
  294. }
  295. }
  296. return elems;
  297. }
  298. public long[] toPackedArray() {
  299. return bits;
  300. }
  301. public String toString() {
  302. return toString(",");
  303. }
  304. /** Transform a bit set into a string by formatting each element as an integer
  305. * @separator The string to put in between elements
  306. * @return A commma-separated list of values
  307. */
  308. public String toString(String separator) {
  309. String str = "";
  310. for (int i = 0; i < (bits.length << LOG_BITS); i++) {
  311. if (member(i)) {
  312. if (str.length() > 0) {
  313. str += separator;
  314. }
  315. str = str + i;
  316. }
  317. }
  318. return str;
  319. }
  320. /** Transform a bit set into a string of characters.
  321. * @separator The string to put in between elements
  322. * @param formatter An object implementing the CharFormatter interface.
  323. * @return A commma-separated list of character constants.
  324. */
  325. public String toString(String separator, CharFormatter formatter) {
  326. String str = "";
  327. for (int i = 0; i < (bits.length << LOG_BITS); i++) {
  328. if (member(i)) {
  329. if (str.length() > 0) {
  330. str += separator;
  331. }
  332. str = str + formatter.literalChar(i);
  333. }
  334. }
  335. return str;
  336. }
  337. /**Create a string representation where instead of integer elements, the
  338. * ith element of vocabulary is displayed instead. Vocabulary is a Vector
  339. * of Strings.
  340. * @separator The string to put in between elements
  341. * @return A commma-separated list of character constants.
  342. */
  343. public String toString(String separator, Vector vocabulary) {
  344. if (vocabulary == null) {
  345. return toString(separator);
  346. }
  347. String str = "";
  348. for (int i = 0; i < (bits.length << LOG_BITS); i++) {
  349. if (member(i)) {
  350. if (str.length() > 0) {
  351. str += separator;
  352. }
  353. if (i >= vocabulary.size()) {
  354. str += "<bad element " + i + ">";
  355. }
  356. else if (vocabulary.elementAt(i) == null) {
  357. str += "<" + i + ">";
  358. }
  359. else {
  360. str += (String)vocabulary.elementAt(i);
  361. }
  362. }
  363. }
  364. return str;
  365. }
  366. /**
  367. * Dump a comma-separated list of the words making up the bit set.
  368. * Split each 64 bit number into two more manageable 32 bit numbers.
  369. * This generates a comma-separated list of C++-like unsigned long constants.
  370. */
  371. public String toStringOfHalfWords() {
  372. String s = new String();
  373. for (int i = 0; i < bits.length; i++) {
  374. if (i != 0) s += ", ";
  375. long tmp = bits[i];
  376. tmp &= 0xFFFFFFFFL;
  377. s += (tmp + "UL");
  378. s += ", ";
  379. tmp = bits[i] >>> 32;
  380. tmp &= 0xFFFFFFFFL;
  381. s += (tmp + "UL");
  382. }
  383. return s;
  384. }
  385. /**
  386. * Dump a comma-separated list of the words making up the bit set.
  387. * This generates a comma-separated list of Java-like long int constants.
  388. */
  389. public String toStringOfWords() {
  390. String s = new String();
  391. for (int i = 0; i < bits.length; i++) {
  392. if (i != 0) s += ", ";
  393. s += (bits[i] + "L");
  394. }
  395. return s;
  396. }
  397. /** Print out the bit set but collapse char ranges. */
  398. public String toStringWithRanges(String separator, CharFormatter formatter) {
  399. String str = "";
  400. int[] elems = this.toArray();
  401. if (elems.length == 0) {
  402. return "";
  403. }
  404. // look for ranges
  405. int i = 0;
  406. while (i < elems.length) {
  407. int lastInRange;
  408. lastInRange = 0;
  409. for (int j = i + 1; j < elems.length; j++) {
  410. if (elems[j] != elems[j - 1] + 1) {
  411. break;
  412. }
  413. lastInRange = j;
  414. }
  415. // found a range
  416. if (str.length() > 0) {
  417. str += separator;
  418. }
  419. if (lastInRange - i >= 2) {
  420. str += formatter.literalChar(elems[i]);
  421. str += "..";
  422. str += formatter.literalChar(elems[lastInRange]);
  423. i = lastInRange; // skip past end of range for next range
  424. }
  425. else { // no range, just print current char and move on
  426. str += formatter.literalChar(elems[i]);
  427. }
  428. i++;
  429. }
  430. return str;
  431. }
  432. private final static int wordNumber(int bit) {
  433. return bit >> LOG_BITS; // bit / BITS
  434. }
  435. }