5 // Ben Maurer (bmaurer@users.sourceforge.net)
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
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.
35 namespace System
.Collections
{
37 public sealed class BitArray
: ICollection
, ICloneable
{
43 public BitArray (BitArray bits
)
46 throw new ArgumentNullException ("bits");
48 _length
= bits
._length
;
49 _array
= new int [(_length
+ 31) / 32];
51 Array
.Copy(bits
._array
, _array
, _array
.Length
);
54 public BitArray (bool [] values
)
57 throw new ArgumentNullException ("values");
59 _length
= values
.Length
;
60 _array
= new int [(_length
+ 31) / 32];
62 for (int i
= 0; i
< values
.Length
; i
++)
63 this [i
] = values
[i
];
66 public BitArray (byte [] bytes
)
69 throw new ArgumentNullException ("bytes");
71 _length
= bytes
.Length
* 8;
72 _array
= new int [(_length
+ 31) / 32];
74 for (int i
= 0; i
< bytes
.Length
; i
++)
75 setByte (i
, bytes
[i
]);
78 public BitArray (int [] values
)
81 throw new ArgumentNullException ("values");
83 int arrlen
= values
.Length
;
85 _array
= new int [arrlen
];
86 Array
.Copy (values
, _array
, arrlen
);
89 public BitArray (int length
)
92 throw new ArgumentOutOfRangeException ("length");
95 _array
= new int [(_length
+ 31) / 32];
98 public BitArray (int length
, bool defaultValue
) : this (length
)
101 for (int i
= 0; i
< _array
.Length
; i
++)
106 private BitArray (int [] array
, int length
)
112 #region Utility Methods
114 byte getByte (int byteIndex
)
116 int index
= byteIndex
/ 4;
117 int shift
= (byteIndex
% 4) * 8;
119 int theByte
= _array
[index
] & (0xff << shift
);
121 return (byte)((theByte
>> shift
) & 0xff);
124 void setByte (int byteIndex
, byte value)
126 int index
= byteIndex
/ 4;
127 int shift
= (byteIndex
% 4) * 8;
130 _array
[index
] &= ~
(0xff << shift
);
131 // or in the new byte
132 _array
[index
] |= value << shift
;
137 void checkOperand (BitArray operand
)
140 throw new ArgumentNullException ();
141 if (operand
._length
!= _length
)
142 throw new ArgumentException ();
147 get { return _length; }
150 public bool IsReadOnly
{
151 get { return false; }
154 public bool IsSynchronized
{
155 get { return false; }
158 public bool this [int index
] {
159 get { return Get (index); }
160 set { Set (index, value); }
164 get { return _length; }
167 throw new ArgumentOutOfRangeException ();
170 if (_length
!= newLen
) {
171 int numints
= (newLen
+ 31) / 32;
172 int [] newArr
= new int [numints
];
173 int copylen
= (numints
> _array
.Length
) ? _array
.Length
: numints
;
174 Array
.Copy (_array
, newArr
, copylen
);
176 // set the internal state
184 public object SyncRoot
{
188 public object Clone ()
190 // LAMESPEC: docs say shallow, MS makes deep.
191 return new BitArray (this);
194 public void CopyTo (Array array
, int index
)
197 throw new ArgumentNullException ("array");
199 throw new ArgumentOutOfRangeException ("index");
202 throw new ArgumentException ("array", "Array rank must be 1");
204 if (index
>= array
.Length
)
205 throw new ArgumentException ("index", "index is greater than array.Length");
207 // in each case, check to make sure enough space in array
209 if (array
is bool []) {
210 if (array
.Length
- index
< _length
)
211 throw new ArgumentException ();
213 bool [] barray
= (bool []) array
;
215 // Copy the bits into the array
216 for (int i
= 0; i
< _length
; i
++)
217 barray
[index
+ i
] = this [i
];
219 } else if (array
is byte []) {
220 int numbytes
= (_length
+ 7) / 8;
222 if ((array
.Length
- index
) < numbytes
)
223 throw new ArgumentException ();
225 byte [] barray
= (byte []) array
;
226 // Copy the bytes into the array
227 for (int i
= 0; i
< numbytes
; i
++)
228 barray
[index
+ i
] = getByte (i
);
230 } else if (array
is int []) {
232 Array
.Copy (_array
, 0, array
, index
, (_length
+ 31) / 32);
235 throw new ArgumentException ("array", "Unsupported type");
239 public BitArray
Not ()
241 int ints
= (_length
+ 31) / 32;
242 for (int i
= 0; i
< ints
; i
++)
243 _array
[i
] = ~_array
[i
];
249 public BitArray
And (BitArray
value)
251 checkOperand (value);
253 int ints
= (_length
+ 31) / 32;
254 for (int i
= 0; i
< ints
; i
++)
255 _array
[i
] &= value._array
[i
];
261 public BitArray
Or (BitArray
value)
263 checkOperand (value);
265 int ints
= (_length
+ 31) / 32;
266 for (int i
= 0; i
< ints
; i
++)
267 _array
[i
] |= value._array
[i
];
273 public BitArray
Xor (BitArray
value)
275 checkOperand (value);
277 int ints
= (_length
+ 31) / 32;
278 for (int i
= 0; i
< ints
; i
++)
279 _array
[i
] ^
= value._array
[i
];
285 public bool Get (int index
)
287 if (index
< 0 || index
>= _length
)
288 throw new ArgumentOutOfRangeException ();
290 return (_array
[index
/ 32] & (1 << (index
% 32))) != 0;
293 public void Set (int index
, bool value)
295 if (index
< 0 || index
>= _length
)
296 throw new ArgumentOutOfRangeException ();
299 _array
[index
/ 32] |= (1 << (index
% 32));
301 _array
[index
/ 32] &= ~
(1 << (index
% 32));
306 public void SetAll (bool value)
309 for (int i
= 0; i
< _array
.Length
; i
++)
313 Array
.Clear (_array
, 0, _array
.Length
);
318 public IEnumerator
GetEnumerator ()
320 return new BitArrayEnumerator (this);
324 class BitArrayEnumerator
: IEnumerator
, ICloneable
{
327 int _index
, _max
, _version
;
329 public object Clone () {
330 return MemberwiseClone ();
333 public BitArrayEnumerator (BitArray ba
)
338 _version
= ba
._version
;
341 public object Current
{
344 throw new InvalidOperationException ("Enum not started");
345 if (_index
>= _bitArray
.Count
)
346 throw new InvalidOperationException ("Enum Ended");
352 public bool MoveNext ()
356 if (_index
< (_bitArray
.Count
- 1)) {
357 _current
= _bitArray
[++_index
];
361 _index
= _bitArray
.Count
;
374 if (_version
!= _bitArray
._version
)
375 throw new InvalidOperationException ();