BitVector32.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. //
  2. // System.Collections.Specialized.BitVector32.cs
  3. //
  4. // Author:
  5. // Miguel de Icaza ([email protected])
  6. // Lawrence Pit ([email protected])
  7. // Andrew Birkett ([email protected])
  8. // Andreas Nahr ([email protected])
  9. //
  10. // (C) Ximian, Inc. http://www.ximian.com
  11. //
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System;
  33. using System.Text;
  34. namespace System.Collections.Specialized {
  35. public struct BitVector32 {
  36. int bits;
  37. public struct Section {
  38. private short mask;
  39. private short offset;
  40. internal Section (short mask, short offset) {
  41. this.mask = mask;
  42. this.offset = offset;
  43. }
  44. public short Mask {
  45. get { return mask; }
  46. }
  47. public short Offset {
  48. get { return offset; }
  49. }
  50. public override bool Equals (object o)
  51. {
  52. if (! (o is Section))
  53. return false;
  54. Section section = (Section) o;
  55. return this.mask == section.mask &&
  56. this.offset == section.offset;
  57. }
  58. public override int GetHashCode ()
  59. {
  60. return (((Int16) mask).GetHashCode () << 16) +
  61. ((Int16) offset).GetHashCode ();
  62. }
  63. public override string ToString ()
  64. {
  65. return "Section{0x" + Convert.ToString(mask, 16) +
  66. ", 0x" + Convert.ToString(offset, 16) + "}";
  67. }
  68. public static string ToString (Section value)
  69. {
  70. StringBuilder b = new StringBuilder ();
  71. b.Append ("Section{0x");
  72. b.Append (Convert.ToString(value.Mask,16));
  73. b.Append (", 0x");
  74. b.Append (Convert.ToString(value.Offset,16));
  75. b.Append ("}");
  76. return b.ToString ();
  77. }
  78. }
  79. // Constructors
  80. public BitVector32 (BitVector32 source)
  81. {
  82. bits = source.bits;
  83. }
  84. public BitVector32 (int init)
  85. {
  86. bits = init;
  87. }
  88. // Properties
  89. public int Data {
  90. get { return bits; }
  91. }
  92. public int this [BitVector32.Section section] {
  93. get {
  94. return ((bits >> section.Offset) & section.Mask);
  95. }
  96. set {
  97. if (value < 0)
  98. throw new ArgumentException ("Section can't hold negative values");
  99. if (value > section.Mask)
  100. throw new ArgumentException ("Value too large to fit in section");
  101. bits &= ~(section.Mask << section.Offset);
  102. bits |= (value << section.Offset);
  103. }
  104. }
  105. public bool this [int mask] {
  106. get {
  107. long tmp = (uint)bits;
  108. return (tmp & (long)mask) == (long)mask;
  109. }
  110. set {
  111. if (value)
  112. bits |= mask;
  113. else
  114. bits &= ~mask;
  115. }
  116. }
  117. // Methods
  118. public static int CreateMask ()
  119. {
  120. return 1;
  121. }
  122. public static int CreateMask (int prev)
  123. {
  124. if (prev == 0)
  125. return 1;
  126. if (prev == Int32.MinValue)
  127. throw new InvalidOperationException ("all bits set");
  128. return prev << 1;
  129. }
  130. public static Section CreateSection (short maxValue)
  131. {
  132. return CreateSection (maxValue, new Section (0, 0));
  133. }
  134. public static Section CreateSection (short maxValue, BitVector32.Section previous)
  135. {
  136. if (maxValue < 1)
  137. throw new ArgumentException ("maxValue");
  138. int bit = HighestSetBit(maxValue) + 1;
  139. int mask = (1 << bit) - 1;
  140. int offset = previous.Offset + NumberOfSetBits (previous.Mask);
  141. if (offset > 32) {
  142. throw new ArgumentException ("Sections cannot exceed 32 bits in total");
  143. }
  144. return new Section ((short) mask, (short) offset);
  145. }
  146. public override bool Equals (object o)
  147. {
  148. if (!(o is BitVector32))
  149. return false;
  150. return bits == ((BitVector32) o).bits;
  151. }
  152. public override int GetHashCode ()
  153. {
  154. return bits.GetHashCode ();
  155. }
  156. public override string ToString ()
  157. {
  158. return ToString (this);
  159. }
  160. public static string ToString (BitVector32 value)
  161. {
  162. StringBuilder b = new StringBuilder ();
  163. b.Append ("BitVector32{");
  164. long mask = (long) 0x80000000;
  165. while (mask > 0) {
  166. b.Append (((value.bits & mask) == 0) ? '0' : '1');
  167. mask >>= 1;
  168. }
  169. b.Append ('}');
  170. return b.ToString ();
  171. }
  172. // Private utilities
  173. private static int NumberOfSetBits (int i)
  174. {
  175. int count = 0;
  176. for (int bit = 0; bit < 32; bit++) {
  177. int mask = 1 << bit;
  178. if ((i & mask) != 0)
  179. count++;
  180. }
  181. return count;
  182. }
  183. private static int HighestSetBit (int i)
  184. {
  185. for (int bit = 31; bit >= 0; bit--) {
  186. int mask = 1 << bit;
  187. if ((mask & i) != 0) {
  188. return bit;
  189. }
  190. }
  191. return -1;
  192. }
  193. }
  194. }