source: trunk/yao/share/antlr-2.7.7/lib/csharp/antlr.runtime/antlr.collections.impl/BitSet.cs @ 1

Last change on this file since 1 was 1, checked in by lnalod, 15 years ago

Initial import of YAO sources

File size: 11.9 KB
Line 
1using System;
2using ArrayList                                 = System.Collections.ArrayList;
3
4//using CharFormatter                           = antlr.CharFormatter;
5
6namespace antlr.collections.impl
7{
8        /*ANTLR Translator Generator
9        * Project led by Terence Parr at http://www.jGuru.com
10        * Software rights: http://www.antlr.org/license.html
11        *
12        * $Id:$
13        */
14
15        //
16        // ANTLR C# Code Generator by Micheal Jordan
17        //                            Kunle Odutola       : kunle UNDERSCORE odutola AT hotmail DOT com
18        //                            Anthony Oguntimehin
19        //
20        // With many thanks to Eric V. Smith from the ANTLR list.
21        //
22       
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!
31        *
32        * Also seems like or() from util is wrong when size of incoming set is bigger
33        * than this.bits.length.
34        *
35        * @author Terence Parr
36        * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
37        */
38
39        public class BitSet : ICloneable
40        {
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
44               
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.
49                */
50                protected internal static readonly int MOD_MASK = BITS - 1;
51               
52                /*The actual data bits */
53                protected internal long[] dataBits;
54               
55                /*Construct a bitset of size one word (64 bits) */
56                public BitSet() : this(BITS)
57                {
58                }
59               
60                /*Construction from a static array of longs */
61                public BitSet(long[] bits_)
62                {
63                        dataBits = bits_;
64                }
65               
66                /*Construct a bitset given the size
67                * @param nbits The size of the bitset in bits
68                */
69                public BitSet(int nbits)
70                {
71                        dataBits = new long[((nbits - 1) >> LOG_BITS) + 1];
72                }
73               
74                /*or this element into this set (grow as necessary to accommodate) */
75                public virtual void  add(int el)
76                {
77                        int n = wordNumber(el);
78                        if (n >= dataBits.Length)
79                        {
80                                growToInclude(el);
81                        }
82                        dataBits[n] |= bitMask(el);
83                }
84               
85                public virtual BitSet and(BitSet a)
86                {
87                        BitSet s = (BitSet) this.Clone();
88                        s.andInPlace(a);
89                        return s;
90                }
91               
92                public virtual void  andInPlace(BitSet a)
93                {
94                        int min = (int) (Math.Min(dataBits.Length, a.dataBits.Length));
95                         for (int i = min - 1; i >= 0; i--)
96                        {
97                                dataBits[i] &= a.dataBits[i];
98                        }
99                        // clear all bits in this not present in a (if this bigger than a).
100                         for (int i = min; i < dataBits.Length; i++)
101                        {
102                                dataBits[i] = 0;
103                        }
104                }
105               
106                private static long bitMask(int bitNumber)
107                {
108                        int bitPosition = bitNumber & MOD_MASK; // bitNumber mod BITS
109                        return 1L << bitPosition;
110                }
111               
112                public virtual void  clear()
113                {
114                         for (int i = dataBits.Length - 1; i >= 0; i--)
115                        {
116                                dataBits[i] = 0;
117                        }
118                }
119               
120                public virtual void  clear(int el)
121                {
122                        int n = wordNumber(el);
123                        if (n >= dataBits.Length)
124                        {
125                                // grow as necessary to accommodate
126                                growToInclude(el);
127                        }
128                        dataBits[n] &= ~ bitMask(el);
129                }
130               
131                public virtual object Clone()
132                {
133                        BitSet s;
134                        try
135                        {
136                                s = new BitSet();
137                                s.dataBits = new long[dataBits.Length];
138                                Array.Copy(dataBits, 0, s.dataBits, 0, dataBits.Length);
139                        }
140                        catch //(System.Exception e)
141                        {
142                                throw new System.ApplicationException();
143                        }
144                        return s;
145                }
146               
147                public virtual int degree()
148                {
149                        int deg = 0;
150                         for (int i = dataBits.Length - 1; i >= 0; i--)
151                        {
152                                long word = dataBits[i];
153                                if (word != 0L)
154                                {
155                                         for (int bit = BITS - 1; bit >= 0; bit--)
156                                        {
157                                                if ((word & (1L << bit)) != 0)
158                                                {
159                                                        deg++;
160                                                }
161                                        }
162                                }
163                        }
164                        return deg;
165                }
166               
167                override public int GetHashCode()
168                {
169                        return dataBits.GetHashCode();
170                }
171
172                /*code "inherited" from java.util.BitSet */
173                override public bool Equals(object obj)
174                {
175                        if ((obj != null) && (obj is BitSet))
176                        {
177                                BitSet bset = (BitSet) obj;
178                               
179                                int n = (int) (System.Math.Min(dataBits.Length, bset.dataBits.Length));
180                                 for (int i = n; i-- > 0; )
181                                {
182                                        if (dataBits[i] != bset.dataBits[i])
183                                        {
184                                                return false;
185                                        }
186                                }
187                                if (dataBits.Length > n)
188                                {
189                                         for (int i = (int) (dataBits.Length); i-- > n; )
190                                        {
191                                                if (dataBits[i] != 0)
192                                                {
193                                                        return false;
194                                                }
195                                        }
196                                }
197                                else if (bset.dataBits.Length > n)
198                                {
199                                         for (int i = (int) (bset.dataBits.Length); i-- > n; )
200                                        {
201                                                if (bset.dataBits[i] != 0)
202                                                {
203                                                        return false;
204                                                }
205                                        }
206                                }
207                                return true;
208                        }
209                        return false;
210                }
211               
212                /*
213                * Grows the set to a larger number of bits.
214                * @param bit element that must fit in set
215                */
216                public virtual void  growToInclude(int bit)
217                {
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;
222                }
223               
224                public virtual bool member(int el)
225                {
226                        int n = wordNumber(el);
227                        if (n >= dataBits.Length)
228                                return false;
229                        return (dataBits[n] & bitMask(el)) != 0;
230                }
231               
232                public virtual bool nil()
233                {
234                         for (int i = dataBits.Length - 1; i >= 0; i--)
235                        {
236                                if (dataBits[i] != 0)
237                                        return false;
238                        }
239                        return true;
240                }
241               
242                public virtual BitSet not()
243                {
244                        BitSet s = (BitSet) this.Clone();
245                        s.notInPlace();
246                        return s;
247                }
248               
249                public virtual void  notInPlace()
250                {
251                         for (int i = dataBits.Length - 1; i >= 0; i--)
252                        {
253                                dataBits[i] = ~ dataBits[i];
254                        }
255                }
256               
257                /*complement bits in the range 0..maxBit. */
258                public virtual void  notInPlace(int maxBit)
259                {
260                        notInPlace(0, maxBit);
261                }
262               
263                /*complement bits in the range minBit..maxBit.*/
264                public virtual void  notInPlace(int minBit, int maxBit)
265                {
266                        // make sure that we have room for maxBit
267                        growToInclude(maxBit);
268                         for (int i = minBit; i <= maxBit; i++)
269                        {
270                                int n = wordNumber(i);
271                                dataBits[n] ^= bitMask(i);
272                        }
273                }
274               
275                private int numWordsToHold(int el)
276                {
277                        return (el >> LOG_BITS) + 1;
278                }
279               
280                public static BitSet of(int el)
281                {
282                        BitSet s = new BitSet(el + 1);
283                        s.add(el);
284                        return s;
285                }
286               
287                /*return this | a in a new set */
288                public virtual BitSet or(BitSet a)
289                {
290                        BitSet s = (BitSet) this.Clone();
291                        s.orInPlace(a);
292                        return s;
293                }
294               
295                public virtual void  orInPlace(BitSet a)
296                {
297                        // If this is smaller than a, grow this first
298                        if (a.dataBits.Length > dataBits.Length)
299                        {
300                                setSize((int) (a.dataBits.Length));
301                        }
302                        int min = (int) (System.Math.Min(dataBits.Length, a.dataBits.Length));
303                         for (int i = min - 1; i >= 0; i--)
304                        {
305                                dataBits[i] |= a.dataBits[i];
306                        }
307                }
308               
309                // remove this element from this set
310                public virtual void  remove(int el)
311                {
312                        int n = wordNumber(el);
313                        if (n >= dataBits.Length)
314                        {
315                                growToInclude(el);
316                        }
317                        dataBits[n] &= ~ bitMask(el);
318                }
319               
320                /*
321                * Sets the size of a set.
322                * @param nwords how many words the new set should be
323                */
324                private void  setSize(int nwords)
325                {
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;
330                }
331               
332                public virtual int size()
333                {
334                        return dataBits.Length << LOG_BITS; // num words * bits per word
335                }
336               
337                /*return how much space is being used by the dataBits array not
338                *  how many actually have member bits on.
339                */
340                public virtual int lengthInLongWords()
341                {
342                        return dataBits.Length;
343                }
344               
345                /*Is this contained within a? */
346                public virtual bool subset(BitSet a)
347                {
348                        if (a == null) //(a == null || !(a is BitSet))
349                                return false;
350                        return this.and(a).Equals(this);
351                }
352               
353                /*Subtract the elements of 'a' from 'this' in-place.
354                * Basically, just turn off all bits of 'this' that are in 'a'.
355                */
356                public virtual void  subtractInPlace(BitSet a)
357                {
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++)
362                        {
363                                dataBits[i] &= ~ a.dataBits[i];
364                        }
365                }
366               
367                public virtual int[] toArray()
368                {
369                        int[] elems = new int[degree()];
370                        int en = 0;
371                         for (int i = 0; i < (dataBits.Length << LOG_BITS); i++)
372                        {
373                                if (member(i))
374                                {
375                                        elems[en++] = i;
376                                }
377                        }
378                        return elems;
379                }
380               
381                public virtual long[] toPackedArray()
382                {
383                        return dataBits;
384                }
385               
386                override public string ToString()
387                {
388                        return ToString(",");
389                }
390               
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
394                */
395                public virtual string ToString(string separator)
396                {
397                        string str = "";
398                         for (int i = 0; i < (dataBits.Length << LOG_BITS); i++)
399                        {
400                                if (member(i))
401                                {
402                                        if (str.Length > 0)
403                                        {
404                                                str += separator;
405                                        }
406                                        str = str + i;
407                                }
408                        }
409                        return str;
410                }
411               
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.
417                */
418                public virtual string ToString(string separator, ArrayList vocabulary)
419                {
420                        if (vocabulary == null)
421                        {
422                                return ToString(separator);
423                        }
424                        string str = "";
425                         for (int i = 0; i < (dataBits.Length << LOG_BITS); i++)
426                        {
427                                if (member(i))
428                                {
429                                        if (str.Length > 0)
430                                        {
431                                                str += separator;
432                                        }
433                                        if (i >= vocabulary.Count)
434                                        {
435                                                str += "<bad element " + i + ">";
436                                        }
437                                        else if (vocabulary[i] == null)
438                                        {
439                                                str += "<" + i + ">";
440                                        }
441                                        else
442                                        {
443                                                str += (string) vocabulary[i];
444                                        }
445                                }
446                        }
447                        return str;
448                }
449               
450                /*
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.
454                */
455                public virtual string toStringOfHalfWords()
456                {
457                        string s = new string("".ToCharArray());
458                         for (int i = 0; i < dataBits.Length; i++)
459                        {
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");
469                        }
470                        return s;
471                }
472               
473                /*
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.
476                */
477                public virtual string toStringOfWords()
478                {
479                        string s = new string("".ToCharArray());
480                         for (int i = 0; i < dataBits.Length; i++)
481                        {
482                                if (i != 0)
483                                        s += ", ";
484                                s += (dataBits[i] + "L");
485                        }
486                        return s;
487                }
488               
489                /*Print out the bit set but collapse char ranges. */
490/*              public virtual string toStringWithRanges(string separator, CharFormatter formatter)
491                {
492                        string str = "";
493                        int[] elems = this.toArray();
494                        if (elems.Length == 0)
495                        {
496                                return "";
497                        }
498                        // look for ranges
499                        int i = 0;
500                        while (i < elems.Length)
501                        {
502                                int lastInRange;
503                                lastInRange = 0;
504                                 for (int j = i + 1; j < elems.Length; j++)
505                                {
506                                        if (elems[j] != elems[j - 1] + 1)
507                                        {
508                                                break;
509                                        }
510                                        lastInRange = j;
511                                }
512                                // found a range
513                                if (str.Length > 0)
514                                {
515                                        str += separator;
516                                }
517                                if (lastInRange - i >= 2)
518                                {
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
523                                }
524                                else
525                                {
526                                        // no range, just print current char and move on
527                                        str += formatter.literalChar(elems[i]);
528                                }
529                                i++;
530                        }
531                        return str;
532                }
533*/             
534                private static int wordNumber(int bit)
535                {
536                        return bit >> LOG_BITS; // bit / BITS
537                }
538        }
539}
Note: See TracBrowser for help on using the repository browser.