1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD licence"]
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2005-2008 Terence Parr
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Conversion to C#:
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved.
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met:
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    notice, this list of conditions and the following disclaimer.
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    notice, this list of conditions and the following disclaimer in the
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    documentation and/or other materials provided with the distribution.
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    derived from this software without specific prior written permission.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace Antlr.Runtime {
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using System.Collections.Generic;
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Array = System.Array;
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using CLSCompliant = System.CLSCompliantAttribute;
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using ICloneable = System.ICloneable;
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Math = System.Math;
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using StringBuilder = System.Text.StringBuilder;
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** <summary>
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  A stripped-down version of org.antlr.misc.BitSet that is just
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  good enough to handle runtime requirements such as FOLLOW sets
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  for automatic error recovery.
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  </summary>
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    [System.Serializable]
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public sealed class BitSet : ICloneable {
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private const int BITS = 64;    // number of bits / long
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private const int LOG_BITS = 6; // 2^6 == 64
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  We will often need to do a mod operator (i mod nbits).  Its
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  turns out that, for powers of two, this mod operation is
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  same as (i & (nbits-1)).  Since mod is slow, we use a
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  precomputed mod mask to do the mod instead.
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private const int MOD_MASK = BITS - 1;
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>The actual data bits</summary> */
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ulong[] _bits;
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Construct a bitset of size one word (64 bits)</summary> */
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet()
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            : this(BITS) {
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Construction from a static array of longs</summary> */
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet(ulong[] bits) {
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            _bits = bits;
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Construction from a list of integers</summary> */
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet(IEnumerable<int> items)
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            : this() {
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (int i in items)
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Add(i);
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Construct a bitset given the size</summary>
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  <param name="nbits">The size of the bitset in bits</param>
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet(int nbits) {
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            _bits = new ulong[((nbits - 1) >> LOG_BITS) + 1];
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static BitSet Of(int el) {
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = new BitSet(el + 1);
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(el);
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static BitSet Of(int a, int b) {
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = new BitSet(Math.Max(a, b) + 1);
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(a);
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(b);
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static BitSet Of(int a, int b, int c) {
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = new BitSet();
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(a);
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(b);
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(c);
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static BitSet Of(int a, int b, int c, int d) {
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = new BitSet();
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(a);
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(b);
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(c);
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add(d);
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>return this | a in a new set</summary> */
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet Or(BitSet a) {
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (a == null) {
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return this;
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = (BitSet)this.Clone();
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.OrInPlace(a);
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>or this element into this set (grow as necessary to accommodate)</summary> */
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public void Add(int el) {
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = WordNumber(el);
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (n >= _bits.Length) {
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                GrowToInclude(el);
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            _bits[n] |= BitMask(el);
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Grows the set to a larger number of bits.</summary>
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  <param name="bit">element that must fit in set</param>
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public void GrowToInclude(int bit) {
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int newSize = Math.Max(_bits.Length << 1, NumWordsToHold(bit));
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            SetSize(newSize);
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public void OrInPlace(BitSet a) {
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (a == null) {
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return;
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // If this is smaller than a, grow this first
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (a._bits.Length > _bits.Length) {
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                SetSize(a._bits.Length);
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int min = Math.Min(_bits.Length, a._bits.Length);
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for (int i = min - 1; i >= 0; i--) {
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                _bits[i] |= a._bits[i];
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Sets the size of a set.</summary>
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  <param name="nwords">how many words the new set should be</param>
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private void SetSize(int nwords) {
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Array.Resize(ref _bits, nwords);
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private static ulong BitMask(int bitNumber) {
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int bitPosition = bitNumber & MOD_MASK; // bitNumber mod BITS
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 1UL << bitPosition;
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public object Clone() {
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return new BitSet((ulong[])_bits.Clone());
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public int Size() {
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int deg = 0;
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for (int i = _bits.Length - 1; i >= 0; i--) {
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ulong word = _bits[i];
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (word != 0L) {
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    for (int bit = BITS - 1; bit >= 0; bit--) {
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        if ((word & (1UL << bit)) != 0) {
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            deg++;
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        }
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return deg;
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override int GetHashCode() {
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new System.NotImplementedException();
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override bool Equals(object other) {
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (other == null || !(other is BitSet)) {
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return false;
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet otherSet = (BitSet)other;
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = Math.Min(this._bits.Length, otherSet._bits.Length);
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // for any bits in common, compare
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for (int i = 0; i < n; i++) {
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (this._bits[i] != otherSet._bits[i]) {
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    return false;
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // make sure any extra bits are off
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (this._bits.Length > n) {
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                for (int i = n + 1; i < this._bits.Length; i++) {
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if (this._bits[i] != 0) {
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        return false;
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } else if (otherSet._bits.Length > n) {
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                for (int i = n + 1; i < otherSet._bits.Length; i++) {
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if (otherSet._bits[i] != 0) {
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        return false;
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return true;
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public bool Member(int el) {
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (el < 0) {
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return false;
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = WordNumber(el);
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (n >= _bits.Length)
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return false;
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return (_bits[n] & BitMask(el)) != 0;
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // remove this element from this set
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public void Remove(int el) {
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = WordNumber(el);
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (n < _bits.Length) {
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                _bits[n] &= ~BitMask(el);
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public bool IsNil() {
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for (int i = _bits.Length - 1; i >= 0; i--) {
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (_bits[i] != 0)
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    return false;
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return true;
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private static int NumWordsToHold(int el) {
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return (el >> LOG_BITS) + 1;
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public int NumBits() {
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return _bits.Length << LOG_BITS; // num words * bits per word
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>return how much space is being used by the bits array not how many actually have member bits on.</summary> */
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public int LengthInLongWords() {
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return _bits.Length;
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /**Is this contained within a? */
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /*
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public boolean subset(BitSet a) {
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (a == null || !(a instanceof BitSet)) return false;
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return this.and(a).equals(this);
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        */
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public int[] ToArray() {
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int[] elems = new int[Size()];
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int en = 0;
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for (int i = 0; i < (_bits.Length << LOG_BITS); i++) {
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (Member(i)) {
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    elems[en++] = i;
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return elems;
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private static int WordNumber(int bit) {
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return bit >> LOG_BITS; // bit / BITS
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override string ToString() {
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ToString(null);
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public string ToString(string[] tokenNames) {
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            StringBuilder buf = new StringBuilder();
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            string separator = ",";
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            bool havePrintedAnElement = false;
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append('{');
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for (int i = 0; i < (_bits.Length << LOG_BITS); i++) {
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (Member(i)) {
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if (i > 0 && havePrintedAnElement) {
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        buf.Append(separator);
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if (tokenNames != null) {
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        buf.Append(tokenNames[i]);
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    } else {
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        buf.Append(i);
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    havePrintedAnElement = true;
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append('}');
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return buf.ToString();
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
320