Mercurial > projects > ldc
comparison tango/tango/core/BitArray.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /** | |
2 * This module contains a packed bit array implementation in the style of D's | |
3 * built-in dynamic arrays. | |
4 * | |
5 * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com. | |
6 * All rights reserved. | |
7 * License: BSD style: $(LICENSE) | |
8 * Authors: Walter Bright, Sean Kelly | |
9 */ | |
10 module tango.core.BitArray; | |
11 | |
12 | |
13 private import tango.core.BitManip; | |
14 | |
15 | |
16 /** | |
17 * An array of bits. | |
18 */ | |
19 struct BitArray | |
20 { | |
21 size_t len; | |
22 uint* ptr; | |
23 | |
24 | |
25 /** | |
26 * | |
27 */ | |
28 static BitArray opCall( bool[] bits ) | |
29 { | |
30 BitArray temp; | |
31 | |
32 temp.length = bits.length; | |
33 foreach( pos, val; bits ) | |
34 temp[pos] = val; | |
35 return temp; | |
36 } | |
37 | |
38 /** | |
39 * | |
40 */ | |
41 size_t length() | |
42 { | |
43 return len; | |
44 } | |
45 | |
46 | |
47 /** | |
48 * | |
49 */ | |
50 void length(size_t newlen) | |
51 { | |
52 if (newlen != len) | |
53 { | |
54 size_t olddim = dim(); | |
55 size_t newdim = (newlen + 31) / 32; | |
56 | |
57 if (newdim != olddim) | |
58 { | |
59 // Create a fake array so we can use D's realloc machinery | |
60 uint[] b = ptr[0 .. olddim]; | |
61 | |
62 b.length = newdim; // realloc | |
63 ptr = b.ptr; | |
64 if (newdim & 31) | |
65 { | |
66 // Set any pad bits to 0 | |
67 ptr[newdim - 1] &= ~(~0 << (newdim & 31)); | |
68 } | |
69 } | |
70 len = newlen; | |
71 } | |
72 } | |
73 | |
74 | |
75 /** | |
76 * | |
77 */ | |
78 size_t dim() | |
79 { | |
80 return (len + 31) / 32; | |
81 } | |
82 | |
83 | |
84 /** | |
85 * Support for array.dup property for BitArray. | |
86 */ | |
87 BitArray dup() | |
88 { | |
89 BitArray ba; | |
90 | |
91 uint[] b = ptr[0 .. dim].dup; | |
92 ba.len = len; | |
93 ba.ptr = b.ptr; | |
94 return ba; | |
95 } | |
96 | |
97 | |
98 debug( UnitTest ) | |
99 { | |
100 unittest | |
101 { | |
102 BitArray a; | |
103 BitArray b; | |
104 int i; | |
105 | |
106 a.length = 3; | |
107 a[0] = 1; a[1] = 0; a[2] = 1; | |
108 b = a.dup; | |
109 assert(b.length == 3); | |
110 for (i = 0; i < 3; i++) | |
111 { | |
112 //printf("b[%d] = %d\n", i, b[i]); | |
113 assert(b[i] == (((i ^ 1) & 1) ? true : false)); | |
114 } | |
115 } | |
116 } | |
117 | |
118 | |
119 /** | |
120 * Set BitArray to contents of ba[] | |
121 */ | |
122 void opAssign(bool[] ba) | |
123 { | |
124 length = ba.length; | |
125 foreach (i, b; ba) | |
126 { | |
127 (*this)[i] = b; | |
128 } | |
129 } | |
130 | |
131 | |
132 /** | |
133 * Map BitArray onto v[], with numbits being the number of bits | |
134 * in the array. Does not copy the data. | |
135 * | |
136 * This is the inverse of opCast. | |
137 */ | |
138 void init(void[] v, size_t numbits) | |
139 in | |
140 { | |
141 assert(numbits <= v.length * 8); | |
142 assert((v.length & 3) == 0); | |
143 } | |
144 body | |
145 { | |
146 ptr = cast(uint*)v.ptr; | |
147 len = numbits; | |
148 } | |
149 | |
150 | |
151 debug( UnitTest ) | |
152 { | |
153 unittest | |
154 { | |
155 BitArray a = [1,0,1,0,1]; | |
156 BitArray b; | |
157 void[] v; | |
158 | |
159 v = cast(void[])a; | |
160 b.init(v, a.length); | |
161 | |
162 assert(b[0] == 1); | |
163 assert(b[1] == 0); | |
164 assert(b[2] == 1); | |
165 assert(b[3] == 0); | |
166 assert(b[4] == 1); | |
167 | |
168 a[0] = 0; | |
169 assert(b[0] == 0); | |
170 | |
171 assert(a == b); | |
172 } | |
173 } | |
174 | |
175 | |
176 /** | |
177 * Support for array.reverse property for BitArray. | |
178 */ | |
179 BitArray reverse() | |
180 out (result) | |
181 { | |
182 assert(result == *this); | |
183 } | |
184 body | |
185 { | |
186 if (len >= 2) | |
187 { | |
188 bool t; | |
189 size_t lo, hi; | |
190 | |
191 lo = 0; | |
192 hi = len - 1; | |
193 for (; lo < hi; lo++, hi--) | |
194 { | |
195 t = (*this)[lo]; | |
196 (*this)[lo] = (*this)[hi]; | |
197 (*this)[hi] = t; | |
198 } | |
199 } | |
200 return *this; | |
201 } | |
202 | |
203 | |
204 debug( UnitTest ) | |
205 { | |
206 unittest | |
207 { | |
208 BitArray b; | |
209 static bool[5] data = [1,0,1,1,0]; | |
210 int i; | |
211 | |
212 b = data; | |
213 b.reverse; | |
214 for (i = 0; i < data.length; i++) | |
215 { | |
216 assert(b[i] == data[4 - i]); | |
217 } | |
218 } | |
219 } | |
220 | |
221 | |
222 /** | |
223 * Support for array.sort property for BitArray. | |
224 */ | |
225 BitArray sort() | |
226 out (result) | |
227 { | |
228 assert(result == *this); | |
229 } | |
230 body | |
231 { | |
232 if (len >= 2) | |
233 { | |
234 size_t lo, hi; | |
235 | |
236 lo = 0; | |
237 hi = len - 1; | |
238 while (1) | |
239 { | |
240 while (1) | |
241 { | |
242 if (lo >= hi) | |
243 goto Ldone; | |
244 if ((*this)[lo] == true) | |
245 break; | |
246 lo++; | |
247 } | |
248 | |
249 while (1) | |
250 { | |
251 if (lo >= hi) | |
252 goto Ldone; | |
253 if ((*this)[hi] == false) | |
254 break; | |
255 hi--; | |
256 } | |
257 | |
258 (*this)[lo] = false; | |
259 (*this)[hi] = true; | |
260 | |
261 lo++; | |
262 hi--; | |
263 } | |
264 Ldone: | |
265 ; | |
266 } | |
267 return *this; | |
268 } | |
269 | |
270 | |
271 debug( UnitTest ) | |
272 { | |
273 unittest | |
274 { | |
275 static uint x = 0b1100011000; | |
276 static BitArray ba = { 10, &x }; | |
277 | |
278 ba.sort; | |
279 for (size_t i = 0; i < 6; i++) | |
280 assert(ba[i] == false); | |
281 for (size_t i = 6; i < 10; i++) | |
282 assert(ba[i] == true); | |
283 } | |
284 } | |
285 | |
286 | |
287 /** | |
288 * Support for foreach loops for BitArray. | |
289 */ | |
290 int opApply(int delegate(inout bool) dg) | |
291 { | |
292 int result; | |
293 | |
294 for (size_t i = 0; i < len; i++) | |
295 { | |
296 bool b = opIndex(i); | |
297 result = dg(b); | |
298 opIndexAssign(b,i); | |
299 if (result) | |
300 break; | |
301 } | |
302 return result; | |
303 } | |
304 | |
305 /** ditto */ | |
306 int opApply(int delegate(inout size_t, inout bool) dg) | |
307 { | |
308 int result; | |
309 | |
310 for (size_t i = 0; i < len; i++) | |
311 { | |
312 bool b = opIndex(i); | |
313 result = dg(i, b); | |
314 opIndexAssign(b,i); | |
315 if (result) | |
316 break; | |
317 } | |
318 return result; | |
319 } | |
320 | |
321 | |
322 debug( UnitTest ) | |
323 { | |
324 unittest | |
325 { | |
326 BitArray a = [1,0,1]; | |
327 | |
328 int i; | |
329 foreach (b;a) | |
330 { | |
331 switch (i) | |
332 { | |
333 case 0: assert(b == true); break; | |
334 case 1: assert(b == false); break; | |
335 case 2: assert(b == true); break; | |
336 default: assert(0); | |
337 } | |
338 i++; | |
339 } | |
340 | |
341 foreach (j,b;a) | |
342 { | |
343 switch (j) | |
344 { | |
345 case 0: assert(b == true); break; | |
346 case 1: assert(b == false); break; | |
347 case 2: assert(b == true); break; | |
348 default: assert(0); | |
349 } | |
350 } | |
351 } | |
352 } | |
353 | |
354 | |
355 /** | |
356 * Support for operators == and != for bit arrays. | |
357 */ | |
358 int opEquals(BitArray a2) | |
359 { | |
360 int i; | |
361 | |
362 if (this.length != a2.length) | |
363 return 0; // not equal | |
364 byte *p1 = cast(byte*)this.ptr; | |
365 byte *p2 = cast(byte*)a2.ptr; | |
366 uint n = this.length / 8; | |
367 for (i = 0; i < n; i++) | |
368 { | |
369 if (p1[i] != p2[i]) | |
370 return 0; // not equal | |
371 } | |
372 | |
373 ubyte mask; | |
374 | |
375 n = this.length & 7; | |
376 mask = cast(ubyte)((1 << n) - 1); | |
377 //printf("i = %d, n = %d, mask = %x, %x, %x\n", i, n, mask, p1[i], p2[i]); | |
378 return (mask == 0) || (p1[i] & mask) == (p2[i] & mask); | |
379 } | |
380 | |
381 debug( UnitTest ) | |
382 { | |
383 unittest | |
384 { | |
385 BitArray a = [1,0,1,0,1]; | |
386 BitArray b = [1,0,1]; | |
387 BitArray c = [1,0,1,0,1,0,1]; | |
388 BitArray d = [1,0,1,1,1]; | |
389 BitArray e = [1,0,1,0,1]; | |
390 | |
391 assert(a != b); | |
392 assert(a != c); | |
393 assert(a != d); | |
394 assert(a == e); | |
395 } | |
396 } | |
397 | |
398 | |
399 /** | |
400 * Implement comparison operators. | |
401 */ | |
402 int opCmp(BitArray a2) | |
403 { | |
404 uint len; | |
405 uint i; | |
406 | |
407 len = this.length; | |
408 if (a2.length < len) | |
409 len = a2.length; | |
410 ubyte* p1 = cast(ubyte*)this.ptr; | |
411 ubyte* p2 = cast(ubyte*)a2.ptr; | |
412 uint n = len / 8; | |
413 for (i = 0; i < n; i++) | |
414 { | |
415 if (p1[i] != p2[i]) | |
416 break; // not equal | |
417 } | |
418 for (uint j = i * 8; j < len; j++) | |
419 { ubyte mask = cast(ubyte)(1 << j); | |
420 int c; | |
421 | |
422 c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask); | |
423 if (c) | |
424 return c; | |
425 } | |
426 return cast(int)this.len - cast(int)a2.length; | |
427 } | |
428 | |
429 debug( UnitTest ) | |
430 { | |
431 unittest | |
432 { | |
433 BitArray a = [1,0,1,0,1]; | |
434 BitArray b = [1,0,1]; | |
435 BitArray c = [1,0,1,0,1,0,1]; | |
436 BitArray d = [1,0,1,1,1]; | |
437 BitArray e = [1,0,1,0,1]; | |
438 | |
439 assert(a > b); | |
440 assert(a >= b); | |
441 assert(a < c); | |
442 assert(a <= c); | |
443 assert(a < d); | |
444 assert(a <= d); | |
445 assert(a == e); | |
446 assert(a <= e); | |
447 assert(a >= e); | |
448 } | |
449 } | |
450 | |
451 | |
452 /** | |
453 * Convert to void[]. | |
454 */ | |
455 void[] opCast() | |
456 { | |
457 return cast(void[])ptr[0 .. dim]; | |
458 } | |
459 | |
460 | |
461 debug( UnitTest ) | |
462 { | |
463 unittest | |
464 { | |
465 BitArray a = [1,0,1,0,1]; | |
466 void[] v = cast(void[])a; | |
467 | |
468 assert(v.length == a.dim * uint.sizeof); | |
469 } | |
470 } | |
471 | |
472 | |
473 /** | |
474 * Support for [$(I index)] operation for BitArray. | |
475 */ | |
476 bool opIndex(size_t i) | |
477 in | |
478 { | |
479 assert(i < len); | |
480 } | |
481 body | |
482 { | |
483 return cast(bool)bt(ptr, i); | |
484 } | |
485 | |
486 | |
487 /** | |
488 * Support for unary operator ~ for bit arrays. | |
489 */ | |
490 BitArray opCom() | |
491 { | |
492 auto dim = this.dim(); | |
493 | |
494 BitArray result; | |
495 | |
496 result.length = len; | |
497 for (size_t i = 0; i < dim; i++) | |
498 result.ptr[i] = ~this.ptr[i]; | |
499 if (len & 31) | |
500 result.ptr[dim - 1] &= ~(~0 << (len & 31)); | |
501 return result; | |
502 } | |
503 | |
504 | |
505 debug( UnitTest ) | |
506 { | |
507 unittest | |
508 { | |
509 BitArray a = [1,0,1,0,1]; | |
510 BitArray b = ~a; | |
511 | |
512 assert(b[0] == 0); | |
513 assert(b[1] == 1); | |
514 assert(b[2] == 0); | |
515 assert(b[3] == 1); | |
516 assert(b[4] == 0); | |
517 } | |
518 } | |
519 | |
520 | |
521 /** | |
522 * Support for binary operator & for bit arrays. | |
523 */ | |
524 BitArray opAnd(BitArray e2) | |
525 in | |
526 { | |
527 assert(len == e2.length); | |
528 } | |
529 body | |
530 { | |
531 auto dim = this.dim(); | |
532 | |
533 BitArray result; | |
534 | |
535 result.length = len; | |
536 for (size_t i = 0; i < dim; i++) | |
537 result.ptr[i] = this.ptr[i] & e2.ptr[i]; | |
538 return result; | |
539 } | |
540 | |
541 | |
542 debug( UnitTest ) | |
543 { | |
544 unittest | |
545 { | |
546 BitArray a = [1,0,1,0,1]; | |
547 BitArray b = [1,0,1,1,0]; | |
548 | |
549 BitArray c = a & b; | |
550 | |
551 assert(c[0] == 1); | |
552 assert(c[1] == 0); | |
553 assert(c[2] == 1); | |
554 assert(c[3] == 0); | |
555 assert(c[4] == 0); | |
556 } | |
557 } | |
558 | |
559 | |
560 /** | |
561 * Support for binary operator | for bit arrays. | |
562 */ | |
563 BitArray opOr(BitArray e2) | |
564 in | |
565 { | |
566 assert(len == e2.length); | |
567 } | |
568 body | |
569 { | |
570 auto dim = this.dim(); | |
571 | |
572 BitArray result; | |
573 | |
574 result.length = len; | |
575 for (size_t i = 0; i < dim; i++) | |
576 result.ptr[i] = this.ptr[i] | e2.ptr[i]; | |
577 return result; | |
578 } | |
579 | |
580 | |
581 debug( UnitTest ) | |
582 { | |
583 unittest | |
584 { | |
585 BitArray a = [1,0,1,0,1]; | |
586 BitArray b = [1,0,1,1,0]; | |
587 | |
588 BitArray c = a | b; | |
589 | |
590 assert(c[0] == 1); | |
591 assert(c[1] == 0); | |
592 assert(c[2] == 1); | |
593 assert(c[3] == 1); | |
594 assert(c[4] == 1); | |
595 } | |
596 } | |
597 | |
598 | |
599 /** | |
600 * Support for binary operator ^ for bit arrays. | |
601 */ | |
602 BitArray opXor(BitArray e2) | |
603 in | |
604 { | |
605 assert(len == e2.length); | |
606 } | |
607 body | |
608 { | |
609 auto dim = this.dim(); | |
610 | |
611 BitArray result; | |
612 | |
613 result.length = len; | |
614 for (size_t i = 0; i < dim; i++) | |
615 result.ptr[i] = this.ptr[i] ^ e2.ptr[i]; | |
616 return result; | |
617 } | |
618 | |
619 | |
620 debug( UnitTest ) | |
621 { | |
622 unittest | |
623 { | |
624 BitArray a = [1,0,1,0,1]; | |
625 BitArray b = [1,0,1,1,0]; | |
626 | |
627 BitArray c = a ^ b; | |
628 | |
629 assert(c[0] == 0); | |
630 assert(c[1] == 0); | |
631 assert(c[2] == 0); | |
632 assert(c[3] == 1); | |
633 assert(c[4] == 1); | |
634 } | |
635 } | |
636 | |
637 | |
638 /** | |
639 * Support for binary operator - for bit arrays. | |
640 * | |
641 * $(I a - b) for BitArrays means the same thing as $(I a & ~b). | |
642 */ | |
643 BitArray opSub(BitArray e2) | |
644 in | |
645 { | |
646 assert(len == e2.length); | |
647 } | |
648 body | |
649 { | |
650 auto dim = this.dim(); | |
651 | |
652 BitArray result; | |
653 | |
654 result.length = len; | |
655 for (size_t i = 0; i < dim; i++) | |
656 result.ptr[i] = this.ptr[i] & ~e2.ptr[i]; | |
657 return result; | |
658 } | |
659 | |
660 | |
661 debug( UnitTest ) | |
662 { | |
663 unittest | |
664 { | |
665 BitArray a = [1,0,1,0,1]; | |
666 BitArray b = [1,0,1,1,0]; | |
667 | |
668 BitArray c = a - b; | |
669 | |
670 assert(c[0] == 0); | |
671 assert(c[1] == 0); | |
672 assert(c[2] == 0); | |
673 assert(c[3] == 0); | |
674 assert(c[4] == 1); | |
675 } | |
676 } | |
677 | |
678 | |
679 /** | |
680 * Support for binary operator ~ for bit arrays. | |
681 */ | |
682 BitArray opCat(bool b) | |
683 { | |
684 BitArray r; | |
685 | |
686 r = this.dup; | |
687 r.length = len + 1; | |
688 r[len] = b; | |
689 return r; | |
690 } | |
691 | |
692 | |
693 /** ditto */ | |
694 BitArray opCat_r(bool b) | |
695 { | |
696 BitArray r; | |
697 | |
698 r.length = len + 1; | |
699 r[0] = b; | |
700 for (size_t i = 0; i < len; i++) | |
701 r[1 + i] = (*this)[i]; | |
702 return r; | |
703 } | |
704 | |
705 | |
706 /** ditto */ | |
707 BitArray opCat(BitArray b) | |
708 { | |
709 BitArray r; | |
710 | |
711 r = this.dup(); | |
712 r ~= b; | |
713 return r; | |
714 } | |
715 | |
716 | |
717 debug( UnitTest ) | |
718 { | |
719 unittest | |
720 { | |
721 BitArray a = [1,0]; | |
722 BitArray b = [0,1,0]; | |
723 BitArray c; | |
724 | |
725 c = (a ~ b); | |
726 assert(c.length == 5); | |
727 assert(c[0] == 1); | |
728 assert(c[1] == 0); | |
729 assert(c[2] == 0); | |
730 assert(c[3] == 1); | |
731 assert(c[4] == 0); | |
732 | |
733 c = (a ~ true); | |
734 assert(c.length == 3); | |
735 assert(c[0] == 1); | |
736 assert(c[1] == 0); | |
737 assert(c[2] == 1); | |
738 | |
739 c = (false ~ a); | |
740 assert(c.length == 3); | |
741 assert(c[0] == 0); | |
742 assert(c[1] == 1); | |
743 assert(c[2] == 0); | |
744 } | |
745 } | |
746 | |
747 | |
748 /** | |
749 * Support for [$(I index)] operation for BitArray. | |
750 */ | |
751 bool opIndexAssign(bool b, size_t i) | |
752 in | |
753 { | |
754 assert(i < len); | |
755 } | |
756 body | |
757 { | |
758 if (b) | |
759 bts(ptr, i); | |
760 else | |
761 btr(ptr, i); | |
762 return b; | |
763 } | |
764 | |
765 | |
766 /** | |
767 * Support for operator &= bit arrays. | |
768 */ | |
769 BitArray opAndAssign(BitArray e2) | |
770 in | |
771 { | |
772 assert(len == e2.length); | |
773 } | |
774 body | |
775 { | |
776 auto dim = this.dim(); | |
777 | |
778 for (size_t i = 0; i < dim; i++) | |
779 ptr[i] &= e2.ptr[i]; | |
780 return *this; | |
781 } | |
782 | |
783 | |
784 debug( UnitTest ) | |
785 { | |
786 unittest | |
787 { | |
788 BitArray a = [1,0,1,0,1]; | |
789 BitArray b = [1,0,1,1,0]; | |
790 | |
791 a &= b; | |
792 assert(a[0] == 1); | |
793 assert(a[1] == 0); | |
794 assert(a[2] == 1); | |
795 assert(a[3] == 0); | |
796 assert(a[4] == 0); | |
797 } | |
798 } | |
799 | |
800 | |
801 /** | |
802 * Support for operator |= for bit arrays. | |
803 */ | |
804 BitArray opOrAssign(BitArray e2) | |
805 in | |
806 { | |
807 assert(len == e2.length); | |
808 } | |
809 body | |
810 { | |
811 auto dim = this.dim(); | |
812 | |
813 for (size_t i = 0; i < dim; i++) | |
814 ptr[i] |= e2.ptr[i]; | |
815 return *this; | |
816 } | |
817 | |
818 | |
819 debug( UnitTest ) | |
820 { | |
821 unittest | |
822 { | |
823 BitArray a = [1,0,1,0,1]; | |
824 BitArray b = [1,0,1,1,0]; | |
825 | |
826 a |= b; | |
827 assert(a[0] == 1); | |
828 assert(a[1] == 0); | |
829 assert(a[2] == 1); | |
830 assert(a[3] == 1); | |
831 assert(a[4] == 1); | |
832 } | |
833 } | |
834 | |
835 | |
836 /** | |
837 * Support for operator ^= for bit arrays. | |
838 */ | |
839 BitArray opXorAssign(BitArray e2) | |
840 in | |
841 { | |
842 assert(len == e2.length); | |
843 } | |
844 body | |
845 { | |
846 auto dim = this.dim(); | |
847 | |
848 for (size_t i = 0; i < dim; i++) | |
849 ptr[i] ^= e2.ptr[i]; | |
850 return *this; | |
851 } | |
852 | |
853 | |
854 debug( UnitTest ) | |
855 { | |
856 unittest | |
857 { | |
858 BitArray a = [1,0,1,0,1]; | |
859 BitArray b = [1,0,1,1,0]; | |
860 | |
861 a ^= b; | |
862 assert(a[0] == 0); | |
863 assert(a[1] == 0); | |
864 assert(a[2] == 0); | |
865 assert(a[3] == 1); | |
866 assert(a[4] == 1); | |
867 } | |
868 } | |
869 | |
870 | |
871 /** | |
872 * Support for operator -= for bit arrays. | |
873 * | |
874 * $(I a -= b) for BitArrays means the same thing as $(I a &= ~b). | |
875 */ | |
876 BitArray opSubAssign(BitArray e2) | |
877 in | |
878 { | |
879 assert(len == e2.length); | |
880 } | |
881 body | |
882 { | |
883 auto dim = this.dim(); | |
884 | |
885 for (size_t i = 0; i < dim; i++) | |
886 ptr[i] &= ~e2.ptr[i]; | |
887 return *this; | |
888 } | |
889 | |
890 | |
891 debug( UnitTest ) | |
892 { | |
893 unittest | |
894 { | |
895 BitArray a = [1,0,1,0,1]; | |
896 BitArray b = [1,0,1,1,0]; | |
897 | |
898 a -= b; | |
899 assert(a[0] == 0); | |
900 assert(a[1] == 0); | |
901 assert(a[2] == 0); | |
902 assert(a[3] == 0); | |
903 assert(a[4] == 1); | |
904 } | |
905 } | |
906 | |
907 | |
908 /** | |
909 * Support for operator ~= for bit arrays. | |
910 */ | |
911 BitArray opCatAssign(bool b) | |
912 { | |
913 length = len + 1; | |
914 (*this)[len - 1] = b; | |
915 return *this; | |
916 } | |
917 | |
918 | |
919 debug( UnitTest ) | |
920 { | |
921 unittest | |
922 { | |
923 BitArray a = [1,0,1,0,1]; | |
924 BitArray b; | |
925 | |
926 b = (a ~= true); | |
927 assert(a[0] == 1); | |
928 assert(a[1] == 0); | |
929 assert(a[2] == 1); | |
930 assert(a[3] == 0); | |
931 assert(a[4] == 1); | |
932 assert(a[5] == 1); | |
933 | |
934 assert(b == a); | |
935 } | |
936 } | |
937 | |
938 | |
939 /** | |
940 * ditto | |
941 */ | |
942 BitArray opCatAssign(BitArray b) | |
943 { | |
944 auto istart = len; | |
945 length = len + b.length; | |
946 for (auto i = istart; i < len; i++) | |
947 (*this)[i] = b[i - istart]; | |
948 return *this; | |
949 } | |
950 | |
951 | |
952 debug( UnitTest ) | |
953 { | |
954 unittest | |
955 { | |
956 BitArray a = [1,0]; | |
957 BitArray b = [0,1,0]; | |
958 BitArray c; | |
959 | |
960 c = (a ~= b); | |
961 assert(a.length == 5); | |
962 assert(a[0] == 1); | |
963 assert(a[1] == 0); | |
964 assert(a[2] == 0); | |
965 assert(a[3] == 1); | |
966 assert(a[4] == 0); | |
967 | |
968 assert(c == a); | |
969 } | |
970 } | |
971 } |