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{
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using System.Collections.Generic;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Array = System.Array;
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using CLSCompliant = System.CLSCompliantAttribute;
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using ICloneable = System.ICloneable;
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Math = System.Math;
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using StringBuilder = System.Text.StringBuilder;
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** <summary>
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  A stripped-down version of org.antlr.misc.BitSet that is just
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  good enough to handle runtime requirements such as FOLLOW sets
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  for automatic error recovery.
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  </summary>
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    [System.Serializable]
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public sealed class BitSet : ICloneable
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private const int BITS = 64;    // number of bits / long
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private const int LOG_BITS = 6; // 2^6 == 64
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  We will often need to do a mod operator (i mod nbits).  Its
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  turns out that, for powers of two, this mod operation is
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  same as (i & (nbits-1)).  Since mod is slow, we use a
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  precomputed mod mask to do the mod instead.
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private const int MOD_MASK = BITS - 1;
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>The actual data bits</summary> */
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ulong[] _bits;
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Construct a bitset of size one word (64 bits)</summary> */
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet()
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            : this( BITS )
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Construction from a static array of longs</summary> */
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        [CLSCompliant( false )]
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet( ulong[] bits )
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            _bits = bits;
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Construction from a list of integers</summary> */
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet( IEnumerable<int> items )
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            : this()
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach ( int i in items )
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Add( i );
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Construct a bitset given the size</summary>
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  <param name="nbits">The size of the bitset in bits</param>
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet( int nbits )
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            _bits = new ulong[( ( nbits - 1 ) >> LOG_BITS ) + 1];
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static BitSet Of( int el )
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = new BitSet( el + 1 );
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( el );
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static BitSet Of( int a, int b )
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = new BitSet( Math.Max( a, b ) + 1 );
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( a );
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( b );
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static BitSet Of( int a, int b, int c )
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = new BitSet();
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( a );
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( b );
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( c );
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static BitSet Of( int a, int b, int c, int d )
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = new BitSet();
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( a );
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( b );
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( c );
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.Add( d );
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>return this | a in a new set</summary> */
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public BitSet Or( BitSet a )
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( a == null )
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return this;
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet s = (BitSet)this.Clone();
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            s.OrInPlace( a );
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return s;
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>or this element into this set (grow as necessary to accommodate)</summary> */
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public void Add( int el )
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = WordNumber( el );
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( n >= _bits.Length )
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                GrowToInclude( el );
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            _bits[n] |= BitMask( el );
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Grows the set to a larger number of bits.</summary>
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  <param name="bit">element that must fit in set</param>
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public void GrowToInclude( int bit )
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int newSize = Math.Max( _bits.Length << 1, NumWordsToHold( bit ) );
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            SetSize(newSize);
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public void OrInPlace( BitSet a )
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( a == null )
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return;
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // If this is smaller than a, grow this first
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( a._bits.Length > _bits.Length )
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                SetSize( a._bits.Length );
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int min = Math.Min( _bits.Length, a._bits.Length );
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for ( int i = min - 1; i >= 0; i-- )
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                _bits[i] |= a._bits[i];
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Sets the size of a set.</summary>
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  <param name="nwords">how many words the new set should be</param>
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private void SetSize( int nwords )
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Array.Resize(ref _bits, nwords);
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private static ulong BitMask( int bitNumber )
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int bitPosition = bitNumber & MOD_MASK; // bitNumber mod BITS
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 1UL << bitPosition;
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public object Clone()
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return new BitSet( (ulong[])_bits.Clone() );
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public int Size()
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int deg = 0;
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for ( int i = _bits.Length - 1; i >= 0; i-- )
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ulong word = _bits[i];
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( word != 0L )
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    for ( int bit = BITS - 1; bit >= 0; bit-- )
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    {
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        if ( ( word & ( 1UL << bit ) ) != 0 )
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        {
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            deg++;
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        }
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return deg;
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override int GetHashCode()
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new System.NotImplementedException();
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override bool Equals( object other )
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( other == null || !( other is BitSet ) )
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return false;
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            BitSet otherSet = (BitSet)other;
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = Math.Min( this._bits.Length, otherSet._bits.Length );
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // for any bits in common, compare
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for ( int i = 0; i < n; i++ )
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( this._bits[i] != otherSet._bits[i] )
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    return false;
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // make sure any extra bits are off
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( this._bits.Length > n )
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                for ( int i = n + 1; i < this._bits.Length; i++ )
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if ( this._bits[i] != 0 )
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    {
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        return false;
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if ( otherSet._bits.Length > n )
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                for ( int i = n + 1; i < otherSet._bits.Length; i++ )
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if ( otherSet._bits[i] != 0 )
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    {
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        return false;
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return true;
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public bool Member( int el )
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( el < 0 )
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return false;
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = WordNumber( el );
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( n >= _bits.Length )
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return false;
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ( _bits[n] & BitMask( el ) ) != 0;
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // remove this element from this set
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public void Remove( int el )
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = WordNumber( el );
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( n < _bits.Length )
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                _bits[n] &= ~BitMask( el );
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public bool IsNil()
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for ( int i = _bits.Length - 1; i >= 0; i-- )
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( _bits[i] != 0 )
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    return false;
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return true;
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private static int NumWordsToHold( int el )
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ( el >> LOG_BITS ) + 1;
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public int NumBits()
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return _bits.Length << LOG_BITS; // num words * bits per word
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>return how much space is being used by the bits array not how many actually have member bits on.</summary> */
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public int LengthInLongWords()
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return _bits.Length;
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /**Is this contained within a? */
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /*
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public boolean subset(BitSet a) {
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (a == null || !(a instanceof BitSet)) return false;
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return this.and(a).equals(this);
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        */
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public int[] ToArray()
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int[] elems = new int[Size()];
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int en = 0;
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for ( int i = 0; i < ( _bits.Length << LOG_BITS ); i++ )
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( Member( i ) )
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    elems[en++] = i;
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return elems;
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private static int WordNumber( int bit )
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return bit >> LOG_BITS; // bit / BITS
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override string ToString()
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ToString( null );
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public string ToString( string[] tokenNames )
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            StringBuilder buf = new StringBuilder();
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            string separator = ",";
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            bool havePrintedAnElement = false;
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append( '{' );
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for ( int i = 0; i < ( _bits.Length << LOG_BITS ); i++ )
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( Member( i ) )
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if ( i > 0 && havePrintedAnElement )
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    {
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        buf.Append( separator );
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if ( tokenNames != null )
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    {
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        buf.Append( tokenNames[i] );
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    else
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    {
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        buf.Append( i );
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    havePrintedAnElement = true;
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append( '}' );
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return buf.ToString();
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
381