2
0

BitVector32.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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. // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
  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.Text;
  33. namespace System.Collections.Specialized {
  34. public struct BitVector32 {
  35. int bits;
  36. public struct Section {
  37. private short mask;
  38. private short offset;
  39. internal Section (short mask, short offset) {
  40. this.mask = mask;
  41. this.offset = offset;
  42. }
  43. public short Mask {
  44. get { return mask; }
  45. }
  46. public short Offset {
  47. get { return offset; }
  48. }
  49. #if NET_2_0
  50. public bool Equals (Section obj)
  51. {
  52. return this.mask == obj.mask &&
  53. this.offset == obj.offset;
  54. }
  55. #endif
  56. public override bool Equals (object o)
  57. {
  58. if (! (o is Section))
  59. return false;
  60. Section section = (Section) o;
  61. return this.mask == section.mask &&
  62. this.offset == section.offset;
  63. }
  64. public override int GetHashCode ()
  65. {
  66. return (((Int16) mask).GetHashCode () << 16) +
  67. ((Int16) offset).GetHashCode ();
  68. }
  69. public override string ToString ()
  70. {
  71. return "Section{0x" + Convert.ToString(mask, 16) +
  72. ", 0x" + Convert.ToString(offset, 16) + "}";
  73. }
  74. public static string ToString (Section value)
  75. {
  76. StringBuilder b = new StringBuilder ();
  77. b.Append ("Section{0x");
  78. b.Append (Convert.ToString(value.Mask,16));
  79. b.Append (", 0x");
  80. b.Append (Convert.ToString(value.Offset,16));
  81. b.Append ("}");
  82. return b.ToString ();
  83. }
  84. }
  85. // Constructors
  86. public BitVector32 (BitVector32 source)
  87. {
  88. bits = source.bits;
  89. }
  90. public BitVector32 (int init)
  91. {
  92. bits = init;
  93. }
  94. // Properties
  95. public int Data {
  96. get { return bits; }
  97. }
  98. public int this [BitVector32.Section section] {
  99. get {
  100. return ((bits >> section.Offset) & section.Mask);
  101. }
  102. set {
  103. if (value < 0)
  104. throw new ArgumentException ("Section can't hold negative values");
  105. if (value > section.Mask)
  106. throw new ArgumentException ("Value too large to fit in section");
  107. bits &= ~(section.Mask << section.Offset);
  108. bits |= (value << section.Offset);
  109. }
  110. }
  111. public bool this [int mask] {
  112. get {
  113. #if NET_2_0
  114. return (bits & mask) == mask;
  115. #else
  116. long tmp = (uint)bits;
  117. return (tmp & (long)mask) == (long)mask;
  118. #endif
  119. }
  120. set {
  121. if (value)
  122. bits |= mask;
  123. else
  124. bits &= ~mask;
  125. }
  126. }
  127. // Methods
  128. public static int CreateMask ()
  129. {
  130. return 1;
  131. }
  132. public static int CreateMask (int prev)
  133. {
  134. if (prev == 0)
  135. return 1;
  136. if (prev == Int32.MinValue)
  137. throw new InvalidOperationException ("all bits set");
  138. return prev << 1;
  139. }
  140. public static Section CreateSection (short maxValue)
  141. {
  142. return CreateSection (maxValue, new Section (0, 0));
  143. }
  144. public static Section CreateSection (short maxValue, BitVector32.Section previous)
  145. {
  146. if (maxValue < 1)
  147. throw new ArgumentException ("maxValue");
  148. int bit = HighestSetBit(maxValue) + 1;
  149. int mask = (1 << bit) - 1;
  150. int offset = previous.Offset + NumberOfSetBits (previous.Mask);
  151. if (offset > 32) {
  152. throw new ArgumentException ("Sections cannot exceed 32 bits in total");
  153. }
  154. return new Section ((short) mask, (short) offset);
  155. }
  156. public override bool Equals (object o)
  157. {
  158. if (!(o is BitVector32))
  159. return false;
  160. return bits == ((BitVector32) o).bits;
  161. }
  162. public override int GetHashCode ()
  163. {
  164. return bits.GetHashCode ();
  165. }
  166. public override string ToString ()
  167. {
  168. return ToString (this);
  169. }
  170. public static string ToString (BitVector32 value)
  171. {
  172. StringBuilder b = new StringBuilder ();
  173. b.Append ("BitVector32{");
  174. long mask = (long) 0x80000000;
  175. while (mask > 0) {
  176. b.Append (((value.bits & mask) == 0) ? '0' : '1');
  177. mask >>= 1;
  178. }
  179. b.Append ('}');
  180. return b.ToString ();
  181. }
  182. // Private utilities
  183. private static int NumberOfSetBits (int i)
  184. {
  185. int count = 0;
  186. for (int bit = 0; bit < 32; bit++) {
  187. int mask = 1 << bit;
  188. if ((i & mask) != 0)
  189. count++;
  190. }
  191. return count;
  192. }
  193. private static int HighestSetBit (int i)
  194. {
  195. for (int bit = 31; bit >= 0; bit--) {
  196. int mask = 1 << bit;
  197. if ((mask & i) != 0) {
  198. return bit;
  199. }
  200. }
  201. return -1;
  202. }
  203. }
  204. }