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