PageRenderTime 58ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/antlr-3.4/runtime/CSharp3/Sources/Antlr3.Runtime/BitSet.cs

https://gitlab.com/essere.lab.public/qualitas.class-corpus
C# | 380 lines | 268 code | 41 blank | 71 comment | 43 complexity | 866b4e68db0f146ac45fb9c89fa38ce2 MD5 | raw file
  1. /*
  2. * [The "BSD licence"]
  3. * Copyright (c) 2005-2008 Terence Parr
  4. * All rights reserved.
  5. *
  6. * Conversion to C#:
  7. * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * 3. The name of the author may not be used to endorse or promote products
  19. * derived from this software without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  22. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  23. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  24. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  30. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. namespace Antlr.Runtime
  33. {
  34. using System.Collections.Generic;
  35. using Array = System.Array;
  36. using CLSCompliant = System.CLSCompliantAttribute;
  37. using ICloneable = System.ICloneable;
  38. using Math = System.Math;
  39. using StringBuilder = System.Text.StringBuilder;
  40. /** <summary>
  41. * A stripped-down version of org.antlr.misc.BitSet that is just
  42. * good enough to handle runtime requirements such as FOLLOW sets
  43. * for automatic error recovery.
  44. * </summary>
  45. */
  46. [System.Serializable]
  47. public sealed class BitSet : ICloneable
  48. {
  49. private const int BITS = 64; // number of bits / long
  50. private const int LOG_BITS = 6; // 2^6 == 64
  51. /** <summary>
  52. * We will often need to do a mod operator (i mod nbits). Its
  53. * turns out that, for powers of two, this mod operation is
  54. * same as (i & (nbits-1)). Since mod is slow, we use a
  55. * precomputed mod mask to do the mod instead.
  56. * </summary>
  57. */
  58. private const int MOD_MASK = BITS - 1;
  59. /** <summary>The actual data bits</summary> */
  60. ulong[] _bits;
  61. /** <summary>Construct a bitset of size one word (64 bits)</summary> */
  62. public BitSet()
  63. : this( BITS )
  64. {
  65. }
  66. /** <summary>Construction from a static array of longs</summary> */
  67. [CLSCompliant( false )]
  68. public BitSet( ulong[] bits )
  69. {
  70. _bits = bits;
  71. }
  72. /** <summary>Construction from a list of integers</summary> */
  73. public BitSet( IEnumerable<int> items )
  74. : this()
  75. {
  76. foreach ( int i in items )
  77. Add( i );
  78. }
  79. /** <summary>Construct a bitset given the size</summary>
  80. * <param name="nbits">The size of the bitset in bits</param>
  81. */
  82. public BitSet( int nbits )
  83. {
  84. _bits = new ulong[( ( nbits - 1 ) >> LOG_BITS ) + 1];
  85. }
  86. public static BitSet Of( int el )
  87. {
  88. BitSet s = new BitSet( el + 1 );
  89. s.Add( el );
  90. return s;
  91. }
  92. public static BitSet Of( int a, int b )
  93. {
  94. BitSet s = new BitSet( Math.Max( a, b ) + 1 );
  95. s.Add( a );
  96. s.Add( b );
  97. return s;
  98. }
  99. public static BitSet Of( int a, int b, int c )
  100. {
  101. BitSet s = new BitSet();
  102. s.Add( a );
  103. s.Add( b );
  104. s.Add( c );
  105. return s;
  106. }
  107. public static BitSet Of( int a, int b, int c, int d )
  108. {
  109. BitSet s = new BitSet();
  110. s.Add( a );
  111. s.Add( b );
  112. s.Add( c );
  113. s.Add( d );
  114. return s;
  115. }
  116. /** <summary>return this | a in a new set</summary> */
  117. public BitSet Or( BitSet a )
  118. {
  119. if ( a == null )
  120. {
  121. return this;
  122. }
  123. BitSet s = (BitSet)this.Clone();
  124. s.OrInPlace( a );
  125. return s;
  126. }
  127. /** <summary>or this element into this set (grow as necessary to accommodate)</summary> */
  128. public void Add( int el )
  129. {
  130. int n = WordNumber( el );
  131. if ( n >= _bits.Length )
  132. {
  133. GrowToInclude( el );
  134. }
  135. _bits[n] |= BitMask( el );
  136. }
  137. /** <summary>Grows the set to a larger number of bits.</summary>
  138. * <param name="bit">element that must fit in set</param>
  139. */
  140. public void GrowToInclude( int bit )
  141. {
  142. int newSize = Math.Max( _bits.Length << 1, NumWordsToHold( bit ) );
  143. SetSize(newSize);
  144. }
  145. public void OrInPlace( BitSet a )
  146. {
  147. if ( a == null )
  148. {
  149. return;
  150. }
  151. // If this is smaller than a, grow this first
  152. if ( a._bits.Length > _bits.Length )
  153. {
  154. SetSize( a._bits.Length );
  155. }
  156. int min = Math.Min( _bits.Length, a._bits.Length );
  157. for ( int i = min - 1; i >= 0; i-- )
  158. {
  159. _bits[i] |= a._bits[i];
  160. }
  161. }
  162. /** <summary>Sets the size of a set.</summary>
  163. * <param name="nwords">how many words the new set should be</param>
  164. */
  165. private void SetSize( int nwords )
  166. {
  167. Array.Resize(ref _bits, nwords);
  168. }
  169. private static ulong BitMask( int bitNumber )
  170. {
  171. int bitPosition = bitNumber & MOD_MASK; // bitNumber mod BITS
  172. return 1UL << bitPosition;
  173. }
  174. public object Clone()
  175. {
  176. return new BitSet( (ulong[])_bits.Clone() );
  177. }
  178. public int Size()
  179. {
  180. int deg = 0;
  181. for ( int i = _bits.Length - 1; i >= 0; i-- )
  182. {
  183. ulong word = _bits[i];
  184. if ( word != 0L )
  185. {
  186. for ( int bit = BITS - 1; bit >= 0; bit-- )
  187. {
  188. if ( ( word & ( 1UL << bit ) ) != 0 )
  189. {
  190. deg++;
  191. }
  192. }
  193. }
  194. }
  195. return deg;
  196. }
  197. public override int GetHashCode()
  198. {
  199. throw new System.NotImplementedException();
  200. }
  201. public override bool Equals( object other )
  202. {
  203. if ( other == null || !( other is BitSet ) )
  204. {
  205. return false;
  206. }
  207. BitSet otherSet = (BitSet)other;
  208. int n = Math.Min( this._bits.Length, otherSet._bits.Length );
  209. // for any bits in common, compare
  210. for ( int i = 0; i < n; i++ )
  211. {
  212. if ( this._bits[i] != otherSet._bits[i] )
  213. {
  214. return false;
  215. }
  216. }
  217. // make sure any extra bits are off
  218. if ( this._bits.Length > n )
  219. {
  220. for ( int i = n + 1; i < this._bits.Length; i++ )
  221. {
  222. if ( this._bits[i] != 0 )
  223. {
  224. return false;
  225. }
  226. }
  227. }
  228. else if ( otherSet._bits.Length > n )
  229. {
  230. for ( int i = n + 1; i < otherSet._bits.Length; i++ )
  231. {
  232. if ( otherSet._bits[i] != 0 )
  233. {
  234. return false;
  235. }
  236. }
  237. }
  238. return true;
  239. }
  240. public bool Member( int el )
  241. {
  242. if ( el < 0 )
  243. {
  244. return false;
  245. }
  246. int n = WordNumber( el );
  247. if ( n >= _bits.Length )
  248. return false;
  249. return ( _bits[n] & BitMask( el ) ) != 0;
  250. }
  251. // remove this element from this set
  252. public void Remove( int el )
  253. {
  254. int n = WordNumber( el );
  255. if ( n < _bits.Length )
  256. {
  257. _bits[n] &= ~BitMask( el );
  258. }
  259. }
  260. public bool IsNil()
  261. {
  262. for ( int i = _bits.Length - 1; i >= 0; i-- )
  263. {
  264. if ( _bits[i] != 0 )
  265. return false;
  266. }
  267. return true;
  268. }
  269. private static int NumWordsToHold( int el )
  270. {
  271. return ( el >> LOG_BITS ) + 1;
  272. }
  273. public int NumBits()
  274. {
  275. return _bits.Length << LOG_BITS; // num words * bits per word
  276. }
  277. /** <summary>return how much space is being used by the bits array not how many actually have member bits on.</summary> */
  278. public int LengthInLongWords()
  279. {
  280. return _bits.Length;
  281. }
  282. /**Is this contained within a? */
  283. /*
  284. public boolean subset(BitSet a) {
  285. if (a == null || !(a instanceof BitSet)) return false;
  286. return this.and(a).equals(this);
  287. }
  288. */
  289. public int[] ToArray()
  290. {
  291. int[] elems = new int[Size()];
  292. int en = 0;
  293. for ( int i = 0; i < ( _bits.Length << LOG_BITS ); i++ )
  294. {
  295. if ( Member( i ) )
  296. {
  297. elems[en++] = i;
  298. }
  299. }
  300. return elems;
  301. }
  302. private static int WordNumber( int bit )
  303. {
  304. return bit >> LOG_BITS; // bit / BITS
  305. }
  306. public override string ToString()
  307. {
  308. return ToString( null );
  309. }
  310. public string ToString( string[] tokenNames )
  311. {
  312. StringBuilder buf = new StringBuilder();
  313. string separator = ",";
  314. bool havePrintedAnElement = false;
  315. buf.Append( '{' );
  316. for ( int i = 0; i < ( _bits.Length << LOG_BITS ); i++ )
  317. {
  318. if ( Member( i ) )
  319. {
  320. if ( i > 0 && havePrintedAnElement )
  321. {
  322. buf.Append( separator );
  323. }
  324. if ( tokenNames != null )
  325. {
  326. buf.Append( tokenNames[i] );
  327. }
  328. else
  329. {
  330. buf.Append( i );
  331. }
  332. havePrintedAnElement = true;
  333. }
  334. }
  335. buf.Append( '}' );
  336. return buf.ToString();
  337. }
  338. }
  339. }