Fixing an issue with output parameters that are of type IntPtr
[castle.git] / Experiments / Attic / Rook / Castle.Rook.Compiler / Parser / antlr / collections / impl / BitSet.cs
bloba104d76438431264016d3726820a35127df66afe
1 using System;
2 using ArrayList = System.Collections.ArrayList;
4 //using CharFormatter = antlr.CharFormatter;
6 namespace antlr.collections.impl
8 /*ANTLR Translator Generator
9 * Project led by Terence Parr at http://www.jGuru.com
10 * Software rights: http://www.antlr.org/license.html
12 * $Id:$
16 // ANTLR C# Code Generator by Micheal Jordan
17 // Kunle Odutola : kunle UNDERSCORE odutola AT hotmail DOT com
18 // Anthony Oguntimehin
20 // With many thanks to Eric V. Smith from the ANTLR list.
23 /*A BitSet to replace java.util.BitSet.
24 * Primary differences are that most set operators return new sets
25 * as opposed to oring and anding "in place". Further, a number of
26 * operations were added. I cannot contain a BitSet because there
27 * is no way to access the internal bits (which I need for speed)
28 * and, because it is final, I cannot subclass to add functionality.
29 * Consider defining set degree. Without access to the bits, I must
30 * call a method n times to test the ith bit...ack!
32 * Also seems like or() from util is wrong when size of incoming set is bigger
33 * than this.bits.length.
35 * @author Terence Parr
36 * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
39 public class BitSet : ICloneable
41 protected internal const int BITS = 64; // number of bits / long
42 protected internal const int NIBBLE = 4;
43 protected internal const int LOG_BITS = 6; // 2^6 == 64
45 /*We will often need to do a mod operator (i mod nbits). Its
46 * turns out that, for powers of two, this mod operation is
47 * same as (i & (nbits-1)). Since mod is slow, we use a
48 * precomputed mod mask to do the mod instead.
50 protected internal static readonly int MOD_MASK = BITS - 1;
52 /*The actual data bits */
53 protected internal long[] dataBits;
55 /*Construct a bitset of size one word (64 bits) */
56 public BitSet() : this(BITS)
60 /*Construction from a static array of longs */
61 public BitSet(long[] bits_)
63 dataBits = bits_;
66 /*Construct a bitset given the size
67 * @param nbits The size of the bitset in bits
69 public BitSet(int nbits)
71 dataBits = new long[((nbits - 1) >> LOG_BITS) + 1];
74 /*or this element into this set (grow as necessary to accommodate) */
75 public virtual void add(int el)
77 int n = wordNumber(el);
78 if (n >= dataBits.Length)
80 growToInclude(el);
82 dataBits[n] |= bitMask(el);
85 public virtual BitSet and(BitSet a)
87 BitSet s = (BitSet) this.Clone();
88 s.andInPlace(a);
89 return s;
92 public virtual void andInPlace(BitSet a)
94 int min = (int) (Math.Min(dataBits.Length, a.dataBits.Length));
95 for (int i = min - 1; i >= 0; i--)
97 dataBits[i] &= a.dataBits[i];
99 // clear all bits in this not present in a (if this bigger than a).
100 for (int i = min; i < dataBits.Length; i++)
102 dataBits[i] = 0;
106 private static long bitMask(int bitNumber)
108 int bitPosition = bitNumber & MOD_MASK; // bitNumber mod BITS
109 return 1L << bitPosition;
112 public virtual void clear()
114 for (int i = dataBits.Length - 1; i >= 0; i--)
116 dataBits[i] = 0;
120 public virtual void clear(int el)
122 int n = wordNumber(el);
123 if (n >= dataBits.Length)
125 // grow as necessary to accommodate
126 growToInclude(el);
128 dataBits[n] &= ~ bitMask(el);
131 public virtual object Clone()
133 BitSet s;
136 s = new BitSet();
137 s.dataBits = new long[dataBits.Length];
138 Array.Copy(dataBits, 0, s.dataBits, 0, dataBits.Length);
140 catch //(System.Exception e)
142 throw new System.ApplicationException();
144 return s;
147 public virtual int degree()
149 int deg = 0;
150 for (int i = dataBits.Length - 1; i >= 0; i--)
152 long word = dataBits[i];
153 if (word != 0L)
155 for (int bit = BITS - 1; bit >= 0; bit--)
157 if ((word & (1L << bit)) != 0)
159 deg++;
164 return deg;
167 override public int GetHashCode()
169 return dataBits.GetHashCode();
172 /*code "inherited" from java.util.BitSet */
173 override public bool Equals(object obj)
175 if ((obj != null) && (obj is BitSet))
177 BitSet bset = (BitSet) obj;
179 int n = (int) (System.Math.Min(dataBits.Length, bset.dataBits.Length));
180 for (int i = n; i-- > 0; )
182 if (dataBits[i] != bset.dataBits[i])
184 return false;
187 if (dataBits.Length > n)
189 for (int i = (int) (dataBits.Length); i-- > n; )
191 if (dataBits[i] != 0)
193 return false;
197 else if (bset.dataBits.Length > n)
199 for (int i = (int) (bset.dataBits.Length); i-- > n; )
201 if (bset.dataBits[i] != 0)
203 return false;
207 return true;
209 return false;
213 * Grows the set to a larger number of bits.
214 * @param bit element that must fit in set
216 public virtual void growToInclude(int bit)
218 int newSize = (int) (System.Math.Max(dataBits.Length << 1, numWordsToHold(bit)));
219 long[] newbits = new long[newSize];
220 Array.Copy(dataBits, 0, newbits, 0, dataBits.Length);
221 dataBits = newbits;
224 public virtual bool member(int el)
226 int n = wordNumber(el);
227 if (n >= dataBits.Length)
228 return false;
229 return (dataBits[n] & bitMask(el)) != 0;
232 public virtual bool nil()
234 for (int i = dataBits.Length - 1; i >= 0; i--)
236 if (dataBits[i] != 0)
237 return false;
239 return true;
242 public virtual BitSet not()
244 BitSet s = (BitSet) this.Clone();
245 s.notInPlace();
246 return s;
249 public virtual void notInPlace()
251 for (int i = dataBits.Length - 1; i >= 0; i--)
253 dataBits[i] = ~ dataBits[i];
257 /*complement bits in the range 0..maxBit. */
258 public virtual void notInPlace(int maxBit)
260 notInPlace(0, maxBit);
263 /*complement bits in the range minBit..maxBit.*/
264 public virtual void notInPlace(int minBit, int maxBit)
266 // make sure that we have room for maxBit
267 growToInclude(maxBit);
268 for (int i = minBit; i <= maxBit; i++)
270 int n = wordNumber(i);
271 dataBits[n] ^= bitMask(i);
275 private int numWordsToHold(int el)
277 return (el >> LOG_BITS) + 1;
280 public static BitSet of(int el)
282 BitSet s = new BitSet(el + 1);
283 s.add(el);
284 return s;
287 /*return this | a in a new set */
288 public virtual BitSet or(BitSet a)
290 BitSet s = (BitSet) this.Clone();
291 s.orInPlace(a);
292 return s;
295 public virtual void orInPlace(BitSet a)
297 // If this is smaller than a, grow this first
298 if (a.dataBits.Length > dataBits.Length)
300 setSize((int) (a.dataBits.Length));
302 int min = (int) (System.Math.Min(dataBits.Length, a.dataBits.Length));
303 for (int i = min - 1; i >= 0; i--)
305 dataBits[i] |= a.dataBits[i];
309 // remove this element from this set
310 public virtual void remove(int el)
312 int n = wordNumber(el);
313 if (n >= dataBits.Length)
315 growToInclude(el);
317 dataBits[n] &= ~ bitMask(el);
321 * Sets the size of a set.
322 * @param nwords how many words the new set should be
324 private void setSize(int nwords)
326 long[] newbits = new long[nwords];
327 int n = (int) (System.Math.Min(nwords, dataBits.Length));
328 Array.Copy(dataBits, 0, newbits, 0, n);
329 dataBits = newbits;
332 public virtual int size()
334 return dataBits.Length << LOG_BITS; // num words * bits per word
337 /*return how much space is being used by the dataBits array not
338 * how many actually have member bits on.
340 public virtual int lengthInLongWords()
342 return dataBits.Length;
345 /*Is this contained within a? */
346 public virtual bool subset(BitSet a)
348 if (a == null) //(a == null || !(a is BitSet))
349 return false;
350 return this.and(a).Equals(this);
353 /*Subtract the elements of 'a' from 'this' in-place.
354 * Basically, just turn off all bits of 'this' that are in 'a'.
356 public virtual void subtractInPlace(BitSet a)
358 if (a == null)
359 return ;
360 // for all words of 'a', turn off corresponding bits of 'this'
361 for (int i = 0; i < dataBits.Length && i < a.dataBits.Length; i++)
363 dataBits[i] &= ~ a.dataBits[i];
367 public virtual int[] toArray()
369 int[] elems = new int[degree()];
370 int en = 0;
371 for (int i = 0; i < (dataBits.Length << LOG_BITS); i++)
373 if (member(i))
375 elems[en++] = i;
378 return elems;
381 public virtual long[] toPackedArray()
383 return dataBits;
386 override public string ToString()
388 return ToString(",");
391 /*Transform a bit set into a string by formatting each element as an integer
392 * @separator The string to put in between elements
393 * @return A commma-separated list of values
395 public virtual string ToString(string separator)
397 string str = "";
398 for (int i = 0; i < (dataBits.Length << LOG_BITS); i++)
400 if (member(i))
402 if (str.Length > 0)
404 str += separator;
406 str = str + i;
409 return str;
412 /*Create a string representation where instead of integer elements, the
413 * ith element of vocabulary is displayed instead. Vocabulary is a Vector
414 * of Strings.
415 * @separator The string to put in between elements
416 * @return A commma-separated list of character constants.
418 public virtual string ToString(string separator, ArrayList vocabulary)
420 if (vocabulary == null)
422 return ToString(separator);
424 string str = "";
425 for (int i = 0; i < (dataBits.Length << LOG_BITS); i++)
427 if (member(i))
429 if (str.Length > 0)
431 str += separator;
433 if (i >= vocabulary.Count)
435 str += "<bad element " + i + ">";
437 else if (vocabulary[i] == null)
439 str += "<" + i + ">";
441 else
443 str += (string) vocabulary[i];
447 return str;
451 * Dump a comma-separated list of the words making up the bit set.
452 * Split each 64 bit number into two more manageable 32 bit numbers.
453 * This generates a comma-separated list of C++-like unsigned long constants.
455 public virtual string toStringOfHalfWords()
457 string s = new string("".ToCharArray());
458 for (int i = 0; i < dataBits.Length; i++)
460 if (i != 0)
461 s += ", ";
462 long tmp = dataBits[i];
463 tmp &= 0xFFFFFFFFL;
464 s += (tmp + "UL");
465 s += ", ";
466 tmp = SupportClass.URShift(dataBits[i], 32);
467 tmp &= 0xFFFFFFFFL;
468 s += (tmp + "UL");
470 return s;
474 * Dump a comma-separated list of the words making up the bit set.
475 * This generates a comma-separated list of Java-like long int constants.
477 public virtual string toStringOfWords()
479 string s = new string("".ToCharArray());
480 for (int i = 0; i < dataBits.Length; i++)
482 if (i != 0)
483 s += ", ";
484 s += (dataBits[i] + "L");
486 return s;
489 /*Print out the bit set but collapse char ranges. */
490 /* public virtual string toStringWithRanges(string separator, CharFormatter formatter)
492 string str = "";
493 int[] elems = this.toArray();
494 if (elems.Length == 0)
496 return "";
498 // look for ranges
499 int i = 0;
500 while (i < elems.Length)
502 int lastInRange;
503 lastInRange = 0;
504 for (int j = i + 1; j < elems.Length; j++)
506 if (elems[j] != elems[j - 1] + 1)
508 break;
510 lastInRange = j;
512 // found a range
513 if (str.Length > 0)
515 str += separator;
517 if (lastInRange - i >= 2)
519 str += formatter.literalChar(elems[i]);
520 str += "..";
521 str += formatter.literalChar(elems[lastInRange]);
522 i = lastInRange; // skip past end of range for next range
524 else
526 // no range, just print current char and move on
527 str += formatter.literalChar(elems[i]);
529 i++;
531 return str;
534 private static int wordNumber(int bit)
536 return bit >> LOG_BITS; // bit / BITS