modules/up/src/gnug++/BitSet.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- error
- MASK1
- lmask
- rmask
- BSnew
- BitSetalloc
- BitSetresize
- BitSetcopy
- trim
- lcompare
- empty
- count
- BitSetcmpl
- BitSetop
- set
- clear
- clear
- invert
- set
- clear
- invert
- test
- next
- prev
- last
- BitSettoa
- shorttoBitSet
- longtoBitSet
- atoBitSet
- atoBitSet
- printon
- OK
1 /*
2 Copyright (C) 1988 Free Software Foundation
3 written by Doug Lea (dl@rocky.oswego.edu)
4
5 This file is part of the GNU C++ Library. This library is free
6 software; you can redistribute it and/or modify it under the terms of
7 the GNU Library General Public License as published by the Free
8 Software Foundation; either version 2 of the License, or (at your
9 option) any later version. This library is distributed in the hope
10 that it will be useful, but WITHOUT ANY WARRANTY; without even the
11 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the GNU Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public
14 License along with this library; if not, write to the Free Software
15 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 /*
19 BitSet class implementation
20 */
21
22 #ifdef __GNUG__
23 #pragma implementation
24 #endif
25 #include <BitSet.h>
26 #include <std.h>
27 #include <limits.h>
28 #include <Obstack.h>
29 #include <AllocRing.h>
30 #include <new.h>
31 #include <builtin.h>
32 #include <string.h>
33 #include <strstream.h>
34
35 #undef OK
36
37 void BitSet::error(const char* msg) const
/* [<][>][^][v][top][bottom][index][help] */
38 {
39 (*lib_error_handler)("BitSet", msg);
40 }
41
42 // globals & constants
43
44 BitSetRep _nilBitSetRep = { 0, 1, 0, {0} }; // nil BitSets point here
45
46 #define ONES ((_BS_word)(~0L))
47 #define MASK1(BITNO) ((_BS_word)1 << (BITNO))
/* [<][>][^][v][top][bottom][index][help] */
48 #define MAXBitSetRep_SIZE (((_BS_word)1 << (sizeof(unsigned short)*CHAR_BIT - 1)) - 1)
49 #define MINBitSetRep_SIZE (sizeof(_BS_word)*CHAR_BIT)
50
51 #ifndef MALLOC_MIN_OVERHEAD
52 #define MALLOC_MIN_OVERHEAD 4
53 #endif
54
55 // break things up into .s indices and positions
56
57
58 // mask out bits from left
59
60 static inline _BS_word lmask(int p)
/* [<][>][^][v][top][bottom][index][help] */
61 {
62 return ONES << p;
63 }
64
65 // mask out high bits
66
67 static inline _BS_word rmask(int p)
/* [<][>][^][v][top][bottom][index][help] */
68 {
69 return ONES >> (BITSETBITS - 1 - p);
70 }
71
72
73 inline static BitSetRep* BSnew(int newlen)
/* [<][>][^][v][top][bottom][index][help] */
74 {
75 unsigned int siz = sizeof(BitSetRep) + newlen * sizeof(_BS_word)
76 + MALLOC_MIN_OVERHEAD;
77 unsigned int allocsiz = MINBitSetRep_SIZE;;
78 while (allocsiz < siz) allocsiz <<= 1;
79 allocsiz -= MALLOC_MIN_OVERHEAD;
80 if (allocsiz >= MAXBitSetRep_SIZE * sizeof(_BS_word))
81 (*lib_error_handler)("BitSet", "Requested length out of range");
82
83 BitSetRep* rep = new (operator new (allocsiz)) BitSetRep;
84 memset(rep, 0, allocsiz);
85 rep->sz = (allocsiz - sizeof(BitSetRep) + sizeof(_BS_word)) / sizeof(_BS_word);
86 return rep;
87 }
88
89 BitSetRep* BitSetalloc(BitSetRep* old, const _BS_word* src, int srclen,
/* [<][>][^][v][top][bottom][index][help] */
90 int newvirt, int newlen)
91 {
92 if (old == &_nilBitSetRep) old = 0;
93 BitSetRep* rep;
94 if (old == 0 || newlen >= old->sz)
95 rep = BSnew(newlen);
96 else
97 rep = old;
98
99 rep->len = newlen;
100 rep->virt = newvirt;
101
102 if (srclen != 0 && src != rep->s)
103 memcpy(rep->s, src, srclen * sizeof(_BS_word));
104 // BUG fix: extend virtual bit! 20 Oct 1992 Kevin Karplus
105 if (rep->virt)
106 memset(&rep->s[srclen], (char)ONES,
107 (newlen - srclen) * sizeof(_BS_word));
108 if (old != rep && old != 0) delete old;
109 return rep;
110 }
111
112 BitSetRep* BitSetresize(BitSetRep* old, int newlen)
/* [<][>][^][v][top][bottom][index][help] */
113 {
114 BitSetRep* rep;
115 if (old == 0 || old == &_nilBitSetRep)
116 {
117 rep = BSnew(newlen);
118 rep->virt = 0;
119 }
120 else if (newlen >= old->sz)
121 {
122 rep = BSnew(newlen);
123 memcpy(rep->s, old->s, old->len * sizeof(_BS_word));
124 rep->virt = old->virt;
125 // BUG fix: extend virtual bit! 20 Oct 1992 Kevin Karplus
126 if (rep->virt)
127 memset(&rep->s[old->len], (char)ONES,
128 (newlen - old->len) * sizeof(_BS_word));
129 delete old;
130 }
131 else
132 {
133 rep = old;
134 if (rep->len < newlen)
135 memset(&rep->s[rep->len],
136 rep->virt ? (char)ONES : (char)0,
137 (newlen - rep->len) * sizeof(_BS_word));
138 }
139
140 rep->len = newlen;
141
142 return rep;
143 }
144
145 // same, for straight copy
146
147 BitSetRep* BitSetcopy(BitSetRep* old, const BitSetRep* src)
/* [<][>][^][v][top][bottom][index][help] */
148 {
149 BitSetRep* rep;
150 if (old == &_nilBitSetRep) old = 0;
151 if (src == 0 || src == &_nilBitSetRep)
152 {
153 if (old == 0)
154 rep = BSnew(0);
155 else
156 rep = old;
157 rep->len = 0;
158 rep->virt = 0;
159 }
160 else if (old == src)
161 return old;
162 else
163 {
164 int newlen = src->len;
165 if (old == 0 || newlen > old->sz)
166 {
167 rep = BSnew(newlen);
168 if (old != 0) delete old;
169 }
170 else
171 rep = old;
172
173 memcpy(rep->s, src->s, newlen * sizeof(_BS_word));
174 rep->len = newlen;
175 rep->virt = src->virt;
176 }
177 return rep;
178 }
179
180
181 // remove unneeded top bits
182
183 inline static void trim(BitSetRep* rep)
/* [<][>][^][v][top][bottom][index][help] */
184 {
185 int l = rep->len;
186 _BS_word* s = &(rep->s[l - 1]);
187
188 if (rep->virt == 0)
189 while (l > 0 && *s-- == 0) --l;
190 else
191 while (l > 0 && *s-- == ONES) --l;
192 rep->len = l;
193 }
194
195 int operator == (const BitSet& x, const BitSet& y)
196 {
197 if (x.rep->virt != y.rep->virt)
198 return 0;
199 int xl = x.rep->len;
200 int yl = y.rep->len;
201
202 const _BS_word* xs = x.rep->s;
203 const _BS_word* ys = y.rep->s;
204 if (xl < yl) {
205 if (memcmp((void*)xs, (void*)ys, xl * sizeof(_BS_word)))
206 return 0;
207 ys+=xl;
208 const _BS_word* topy = &(ys[yl]);
209 while (ys<topy)
210 if (x.rep->virt?((*ys++)!=ONES):((*ys++)!=0))
211 return 0;
212 }
213 else {
214 if (memcmp((void*)xs, (void*)ys, yl * sizeof(_BS_word)))
215 return 0;
216 if (xl > yl) {
217 xs+=yl;
218 const _BS_word* topx = &(xs[xl]);
219 while (xs<topx)
220 if (y.rep->virt?((*xs++)!=ONES):((*xs++)!=0))
221 return 0;
222 }
223 }
224 return 1;
225 }
226
227 int operator <= (const BitSet& x, const BitSet& y)
228 {
229 if (x.rep->virt > y.rep->virt)
230 return 0;
231
232 int xl = x.rep->len;
233 int yl = y.rep->len;
234
235 const _BS_word* xs = x.rep->s;
236 const _BS_word* ys = y.rep->s;
237 const _BS_word* topx = &(xs[xl]);
238 const _BS_word* topy = &(ys[yl]);
239
240 while (xs < topx && ys < topy)
241 {
242 _BS_word a = *xs++;
243 _BS_word b = *ys++;
244 if ((a | b) != b)
245 return 0;
246 }
247 if (xl < yl) {
248 if (x.rep->virt) {
249 while (ys<topy)
250 if ((*ys++)!=ONES)
251 return 0;
252 }
253 }
254 else if (xl > yl) {
255 if (!y.rep->virt) {
256 while (xs<topx)
257 if ((*xs++)!=0)
258 return 0;
259 }
260 }
261 return 1;
262 }
263
264
265 int operator < (const BitSet& x, const BitSet& y)
266 {
267 if (x.rep->virt > y.rep->virt)
268 return 0;
269
270 int xl = x.rep->len;
271 int yl = y.rep->len;
272
273 _BS_word* xs = x.rep->s;
274 _BS_word* ys = y.rep->s;
275 _BS_word* topx = &(xs[xl]);
276 _BS_word* topy = &(ys[yl]);
277 int one_diff = 0;
278 while (xs < topx && ys < topy)
279 {
280 _BS_word a = *xs++;
281 _BS_word b = *ys++;
282 _BS_word c = a | b;
283 if (c != b)
284 return 0;
285 else if (c != a)
286 one_diff = 1;
287 }
288 if (xl < yl) {
289 if (x.rep->virt) {
290 if (!one_diff)
291 return 0;
292 while (ys<topy)
293 if ((*ys++)!=ONES)
294 return 0;
295 return 1;
296 }
297 else {
298 if (one_diff || y.rep->virt)
299 return 1;
300 while (ys<topy)
301 if ((*ys++)!=0)
302 return 1;
303 return 0;
304 }
305 }
306 else if (xl > yl) {
307 if (y.rep->virt) {
308 if (one_diff || !x.rep->virt)
309 return 1;
310 while (xs<topx)
311 if ((*xs++)!=ONES)
312 return 1;
313 return 0;
314 }
315 else {
316 if (!one_diff)
317 return 0;
318 while (xs<topx)
319 if ((*xs++)!=0)
320 return 0;
321 return 1;
322 }
323 }
324 else
325 return one_diff || x.rep->virt < y.rep->virt;
326 }
327
328 int lcompare(const BitSet& x, const BitSet& y)
/* [<][>][^][v][top][bottom][index][help] */
329 {
330 int xl = x.rep->len;
331 int yl = y.rep->len;
332
333 const _BS_word* xs = x.rep->s;
334 const _BS_word* ys = y.rep->s;
335 const _BS_word* topx = &(xs[xl]);
336 const _BS_word* topy = &(ys[yl]);
337
338 while (xs < topx && ys < topy)
339 {
340 _BS_word a = *xs++;
341 _BS_word b = *ys++;
342 if (a!=b) {
343 #if 0
344 // Faster but opinable
345 return (a<b) ? -1 : 1;
346 #else
347 _BS_word diff=(a^b); // one's where different
348 _BS_word mask=diff&~(diff-1); // first bit different
349 return (a&mask)?1:-1;
350 #endif
351 }
352 if (a<b)
353 return -1;
354 if (a>b)
355 return 1;
356 }
357 if (xl < yl) {
358 if (x.rep->virt) {
359 while (ys<topy)
360 if ((*ys++)!=ONES)
361 return 1;
362 return 0;
363 }
364 else {
365 while (ys<topy)
366 if ((*ys++)!=0)
367 return -1;
368 return 0;
369 }
370 }
371 else if (xl > yl) {
372 if (y.rep->virt) {
373 while (xs<topx)
374 if ((*xs++)!=ONES)
375 return -1;
376 return 0;
377 }
378 else {
379 while (xs<topx)
380 if ((*xs++)!=0)
381 return 1;
382 return 0;
383 }
384 }
385 return 0;
386 }
387
388 int BitSet::empty() const
/* [<][>][^][v][top][bottom][index][help] */
389 {
390 if (rep->virt == 1)
391 return 0;
392
393 _BS_word* bots = rep->s;
394 _BS_word* s = &(bots[rep->len - 1]);
395 while (s >= bots) if (*s-- != 0) return 0;
396 return 1;
397 }
398
399
400 int BitSet::count(int b) const
/* [<][>][^][v][top][bottom][index][help] */
401 {
402 if (b == rep->virt)
403 return -1;
404 int l = 0;
405 _BS_word* s = rep->s;
406 _BS_word* tops = &(s[rep->len]);
407 if (b == 1)
408 {
409 while (s < tops)
410 {
411 _BS_word a = *s++;
412 for (int i = 0; i < BITSETBITS && a != 0; ++i)
413 {
414 if (a & 1)
415 ++l;
416 a >>= 1;
417 }
418 }
419 }
420 else
421 {
422 _BS_word maxbit = MASK1 (BITSETBITS - 1);
423 while (s < tops)
424 {
425 _BS_word a = *s++;
426 for (int i = 0; i < BITSETBITS; ++i)
427 {
428 if ((a & maxbit) == 0)
429 ++l;
430 a <<= 1;
431 }
432 }
433 }
434 return l;
435 }
436
437 BitSetRep* BitSetcmpl(const BitSetRep* src, BitSetRep* r)
/* [<][>][^][v][top][bottom][index][help] */
438 {
439 r = BitSetcopy(r, src);
440 r->virt = !src->virt;
441 _BS_word* rs = r->s;
442 _BS_word* topr = &(rs[r->len]);
443 if (r->len == 0)
444 *rs = ONES;
445 else
446 {
447 while (rs < topr)
448 {
449 _BS_word cmp = ~(*rs);
450 *rs++ = cmp;
451 }
452 }
453 trim(r);
454 return r;
455 }
456
457
458 BitSetRep* BitSetop(const BitSetRep* x, const BitSetRep* y,
/* [<][>][^][v][top][bottom][index][help] */
459 BitSetRep* r, char op)
460 {
461 int xrsame = x == r;
462 int yrsame = y == r;
463 int xv = x->virt;
464 int yv = y->virt;
465 int xl = x->len;
466 int yl = y->len;
467 int rl = (xl >= yl)? xl : yl;
468
469 r = BitSetresize(r, rl);
470 _BS_word* rs = r->s;
471 _BS_word* topr = &(rs[rl]);
472
473 int av, bv;
474 const _BS_word* as;
475 const _BS_word* topa;
476 const _BS_word* bs;
477 const _BS_word* topb;
478
479 if (xl <= yl)
480 {
481 as = (xrsame)? r->s : x->s;
482 av = xv;
483 topa = &(as[xl]);
484 bs = (yrsame)? r->s : y->s;
485 bv = yv;
486 topb = &(bs[yl]);
487 }
488 else
489 {
490 as = (yrsame)? r->s : y->s;
491 av = yv;
492 topa = &(as[yl]);
493 bs = (xrsame)? r->s : x->s;
494 bv = xv;
495 topb = &(bs[xl]);
496 if (op == '-') // reverse sense of difference
497 op = 'D';
498 }
499
500 switch (op)
501 {
502 case '&':
503 r->virt = av & bv;
504 while (as < topa) *rs++ = *as++ & *bs++;
505 if (av)
506 while (rs < topr) *rs++ = *bs++;
507 else
508 while (rs < topr) *rs++ = 0;
509 break;
510 case '|':
511 r->virt = av | bv;
512 while (as < topa) *rs++ = *as++ | *bs++;
513 if (av)
514 while (rs < topr) *rs++ = ONES;
515 else
516 while (rs < topr) *rs++ = *bs++;
517 break;
518 case '^':
519 r->virt = av ^ bv;
520 while (as < topa) *rs++ = *as++ ^ *bs++;
521 if (av)
522 while (rs < topr) *rs++ = ~(*bs++);
523 else
524 while (rs < topr) *rs++ = *bs++;
525 break;
526 case '-':
527 r->virt = av & ~(bv);
528 while (as < topa) *rs++ = *as++ & ~(*bs++);
529 if (av)
530 while (rs < topr) *rs++ = ~(*bs++);
531 else
532 while (rs < topr) *rs++ = 0;
533 break;
534 case 'D':
535 r->virt = ~(av) & (bv);
536 while (as < topa) *rs++ = ~(*as++) & (*bs++);
537 if (av)
538 while (rs < topr) *rs++ = 0;
539 else
540 while (rs < topr) *rs++ = *bs++;
541 break;
542 }
543 trim(r);
544 return r;
545 }
546
547
548 void BitSet::set(int p)
/* [<][>][^][v][top][bottom][index][help] */
549 {
550 if (p < 0) error("Illegal bit index");
551
552 int index = BitSet_index(p);
553 int pos = BitSet_pos(p);
554
555 if (index >= rep->len)
556 {
557 if (rep->virt)
558 return;
559 else
560 rep = BitSetresize(rep, index+1);
561 }
562
563 rep->s[index] |= MASK1 (pos);
564 }
565
566 void BitSet::clear()
/* [<][>][^][v][top][bottom][index][help] */
567 {
568 if (rep->len > 0) memset(rep->s, 0, rep->sz * sizeof(_BS_word));
569 rep->len = rep->virt = 0;
570 }
571
572 void BitSet::clear(int p)
/* [<][>][^][v][top][bottom][index][help] */
573 {
574 if (p < 0) error("Illegal bit index");
575 int index = BitSet_index(p);
576 if (index >= rep->len)
577 {
578 if (rep->virt == 0)
579 return;
580 else
581 rep = BitSetresize(rep, index+1);
582 }
583 rep->s[index] &= ~MASK1(BitSet_pos(p));
584 }
585
586 void BitSet::invert(int p)
/* [<][>][^][v][top][bottom][index][help] */
587 {
588 if (p < 0) error("Illegal bit index");
589 int index = BitSet_index(p);
590 if (index >= rep->len) rep = BitSetresize(rep, index+1);
591 rep->s[index] ^= MASK1(BitSet_pos(p));
592 }
593
594 void BitSet::set(int from, int to)
/* [<][>][^][v][top][bottom][index][help] */
595 {
596 if (from < 0 || from > to) error("Illegal bit index");
597
598 int index1 = BitSet_index(from);
599 int pos1 = BitSet_pos(from);
600
601 if (rep->virt && index1 >= rep->len)
602 return;
603
604 int index2 = BitSet_index(to);
605 int pos2 = BitSet_pos(to);
606
607 if (index2 >= rep->len)
608 rep = BitSetresize(rep, index2+1);
609
610 _BS_word* s = &(rep->s[index1]);
611 _BS_word m1 = lmask(pos1);
612 _BS_word m2 = rmask(pos2);
613 if (index2 == index1)
614 *s |= m1 & m2;
615 else
616 {
617 *s++ |= m1;
618 _BS_word* top = &(rep->s[index2]);
619 *top |= m2;
620 while (s < top)
621 *s++ = ONES;
622 }
623 }
624
625 void BitSet::clear(int from, int to)
/* [<][>][^][v][top][bottom][index][help] */
626 {
627 if (from < 0 || from > to) error("Illegal bit index");
628
629 int index1 = BitSet_index(from);
630 int pos1 = BitSet_pos(from);
631
632 if (!rep->virt && index1 >= rep->len)
633 return;
634
635 int index2 = BitSet_index(to);
636 int pos2 = BitSet_pos(to);
637
638 if (index2 >= rep->len)
639 rep = BitSetresize(rep, index2+1);
640
641 _BS_word* s = &(rep->s[index1]);
642 _BS_word m1 = lmask(pos1);
643 _BS_word m2 = rmask(pos2);
644 if (index2 == index1)
645 *s &= ~(m1 & m2);
646 else
647 {
648 *s++ &= ~m1;
649 _BS_word* top = &(rep->s[index2]);
650 *top &= ~m2;
651 while (s < top)
652 *s++ = 0;
653 }
654 }
655
656 void BitSet::invert(int from, int to)
/* [<][>][^][v][top][bottom][index][help] */
657 {
658 if (from < 0 || from > to) error("Illegal bit index");
659
660 int index1 = BitSet_index(from);
661 int pos1 = BitSet_pos(from);
662 int index2 = BitSet_index(to);
663 int pos2 = BitSet_pos(to);
664
665 if (index2 >= rep->len)
666 rep = BitSetresize(rep, index2+1);
667
668 _BS_word* s = &(rep->s[index1]);
669 _BS_word m1 = lmask(pos1);
670 _BS_word m2 = rmask(pos2);
671 if (index2 == index1)
672 *s ^= m1 & m2;
673 else
674 {
675 *s++ ^= m1;
676 _BS_word* top = &(rep->s[index2]);
677 *top ^= m2;
678 while (s < top)
679 {
680 _BS_word cmp = ~(*s);
681 *s++ = cmp;
682 }
683 }
684 }
685
686
687 int BitSet::test(int from, int to) const
/* [<][>][^][v][top][bottom][index][help] */
688 {
689 if (from < 0 || from > to) return 0;
690
691 int index1 = BitSet_index(from);
692 int pos1 = BitSet_pos(from);
693
694 if (index1 >= rep->len)
695 return rep->virt;
696
697 int index2 = BitSet_index(to);
698 int pos2 = BitSet_pos(to);
699
700 if (index2 >= rep->len)
701 {
702 if (rep->virt)
703 return 1;
704 else
705 {
706 index2 = rep->len - 1;
707 pos2 = BITSETBITS - 1;
708 }
709 }
710
711 _BS_word* s = &(rep->s[index1]);
712 _BS_word m1 = lmask(pos1);
713 _BS_word m2 = rmask(pos2);
714
715 if (index2 == index1)
716 return (*s & m1 & m2) != 0;
717 else
718 {
719 if (*s++ & m1)
720 return 1;
721 _BS_word* top = &(rep->s[index2]);
722 if (*top & m2)
723 return 1;
724 while (s < top)
725 if (*s++ != 0)
726 return 1;
727 return 0;
728 }
729 }
730
731 int BitSet::next(int p, int b) const
/* [<][>][^][v][top][bottom][index][help] */
732 {
733 ++p;
734 int index = BitSet_index(p);
735 int pos = BitSet_pos(p);
736
737 int l = rep->len;
738
739 if (index >= l)
740 {
741 if (rep->virt == b)
742 return p;
743 else
744 return -1;
745 }
746 int j = index;
747 _BS_word* s = rep->s;
748 _BS_word a = s[j] >> pos;
749 int i = pos;
750
751 if (b == 1)
752 {
753 for (; i < BITSETBITS && a != 0; ++i)
754 {
755 if (a & 1)
756 return j * BITSETBITS + i;
757 a >>= 1;
758 }
759 for (++j; j < l; ++j)
760 {
761 a = s[j];
762 for (i = 0; i < BITSETBITS && a != 0; ++i)
763 {
764 if (a & 1)
765 return j * BITSETBITS + i;
766 a >>= 1;
767 }
768 }
769 if (rep->virt)
770 return j * BITSETBITS;
771 else
772 return -1;
773 }
774 else
775 {
776 for (; i < BITSETBITS; ++i)
777 {
778 if ((a & 1) == 0)
779 return j * BITSETBITS + i;
780 a >>= 1;
781 }
782 for (++j; j < l; ++j)
783 {
784 a = s[j];
785 if (a != ONES)
786 {
787 for (i = 0; i < BITSETBITS; ++i)
788 {
789 if ((a & 1) == 0)
790 return j * BITSETBITS + i;
791 a >>= 1;
792 }
793 }
794 }
795 if (!rep->virt)
796 return j * BITSETBITS;
797 else
798 return -1;
799 }
800 }
801
802 int BitSet::prev(int p, int b) const
/* [<][>][^][v][top][bottom][index][help] */
803 {
804 if (--p < 0)
805 return -1;
806
807 int index = BitSet_index(p);
808 int pos = BitSet_pos(p);
809
810 _BS_word* s = rep->s;
811 int l = rep->len;
812
813 if (index >= l)
814 {
815 if (rep->virt == b)
816 return p;
817 else
818 {
819 index = l - 1;
820 pos = BITSETBITS - 1;
821 }
822 }
823
824 int j = index;
825 _BS_word a = s[j];
826
827 int i = pos;
828 _BS_word maxbit = MASK1(pos);
829
830 if (b == 1)
831 {
832 for (; i >= 0 && a != 0; --i)
833 {
834 if (a & maxbit)
835 return j * BITSETBITS + i;
836 a <<= 1;
837 }
838 maxbit = MASK1(BITSETBITS - 1);
839 for (--j; j >= 0; --j)
840 {
841 a = s[j];
842 for (i = BITSETBITS - 1; i >= 0 && a != 0; --i)
843 {
844 if (a & maxbit)
845 return j * BITSETBITS + i;
846 a <<= 1;
847 }
848 }
849 return -1;
850 }
851 else
852 {
853 if (a != ONES)
854 {
855 for (; i >= 0; --i)
856 {
857 if ((a & maxbit) == 0)
858 return j * BITSETBITS + i;
859 a <<= 1;
860 }
861 }
862 maxbit = MASK1(BITSETBITS - 1);
863 for (--j; j >= 0; --j)
864 {
865 a = s[j];
866 if (a != ONES)
867 {
868 for (i = BITSETBITS - 1; i >= 0; --i)
869 {
870 if ((a & maxbit) == 0)
871 return j * BITSETBITS + i;
872 a <<= 1;
873 }
874 }
875 }
876 return -1;
877 }
878 }
879
880 int BitSet::last(int b) const
/* [<][>][^][v][top][bottom][index][help] */
881 {
882 if (b == rep->virt)
883 return -1;
884 else
885 return prev((rep->len) * BITSETBITS, b);
886 }
887
888
889 extern AllocRing _libgxx_fmtq;
890
891 const char* BitSettoa(const BitSet& x, char f, char t, char star)
/* [<][>][^][v][top][bottom][index][help] */
892 {
893 trim(x.rep);
894 int wrksiz = (x.rep->len + 1) * BITSETBITS + 2;
895 char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
896 ostrstream stream(fmtbase, wrksiz);
897
898 x.printon(stream, f, t, star);
899 stream << ends;
900 return fmtbase;
901 }
902
903 BitSet shorttoBitSet(unsigned short i)
/* [<][>][^][v][top][bottom][index][help] */
904 {
905 BitSet r;
906 _BS_word w = i;
907 r.rep = BitSetalloc(0, &w, 1, 0, 2); trim(r.rep);
908 return r;
909 }
910
911 BitSet longtoBitSet(unsigned long i)
/* [<][>][^][v][top][bottom][index][help] */
912 {
913 BitSet r;
914 #if 1
915 _BS_word w = i;
916 r.rep = BitSetalloc(0, &w, 1, 0, 2);
917 #else
918 _BS_word u[2];
919 u[0] = i & ((_BS_word)(~(0)));
920 u[1] = sizeof(long) <= sizeof(_BS_word) ? 0 : i >> BITSETBITS;
921 r.rep = BitSetalloc(0, &u[0], 2, 0, 3);
922 #endif
923 trim(r.rep);
924 return r;
925 }
926
927 #if defined(__GNUG__) && !defined(_G_NO_NRV)
928
929 BitSet atoBitSet(const char* s, char f, char t, char star) return r
/* [<][>][^][v][top][bottom][index][help] */
930 {
931 int sl = strlen(s);
932 if (sl != 0)
933 {
934 r.rep = BitSetresize(r.rep, sl / BITSETBITS + 1);
935 _BS_word* rs = r.rep->s;
936 _BS_word a = 0;
937 _BS_word m = 1;
938 char lastch = 0;
939 unsigned int i = 0;
940 unsigned int l = 1;
941 for(;;)
942 {
943 char ch = s[i];
944 if (ch == t)
945 a |= m;
946 else if (ch == star)
947 {
948 if ((r.rep->virt = (lastch == t)))
949 *rs = a | ~(m - 1);
950 else
951 *rs = a;
952 break;
953 }
954 else if (ch != f)
955 {
956 *rs = a;
957 break;
958 }
959 lastch = ch;
960 if (++i == sl)
961 {
962 *rs = a;
963 break;
964 }
965 else if (i % BITSETBITS == 0)
966 {
967 *rs++ = a;
968 a = 0;
969 m = 1;
970 ++l;
971 }
972 else
973 m <<= 1;
974 }
975 r.rep->len = l;
976 trim(r.rep);
977 }
978 return;
979 }
980
981 #else
982
983 BitSet atoBitSet(const char* s, char f, char t, char star)
/* [<][>][^][v][top][bottom][index][help] */
984 {
985 BitSet r;
986 int sl = strlen(s);
987 if (sl != 0)
988 {
989 r.rep = BitSetresize(r.rep, sl / BITSETBITS + 1);
990 _BS_word* rs = r.rep->s;
991 _BS_word a = 0;
992 _BS_word m = 1;
993 char lastch = 0;
994 unsigned int i = 0;
995 unsigned int l = 1;
996 for(;;)
997 {
998 char ch = s[i];
999 if (ch == t)
1000 a |= m;
1001 else if (ch == star)
1002 {
1003 if (r.rep->virt = lastch == t)
1004 *rs = a | ~(m - 1);
1005 else
1006 *rs = a;
1007 break;
1008 }
1009 else if (ch != f)
1010 {
1011 *rs = a;
1012 break;
1013 }
1014 lastch = ch;
1015 if (++i == sl)
1016 {
1017 *rs = a;
1018 break;
1019 }
1020 else if (i % BITSETBITS == 0)
1021 {
1022 *rs++ = a;
1023 a = 0;
1024 m = 1;
1025 ++l;
1026 }
1027 else
1028 m <<= 1;
1029 }
1030 r.rep->len = l;
1031 trim(r.rep);
1032 }
1033 return r;
1034 }
1035
1036 #endif
1037
1038 ostream& operator << (ostream& s, const BitSet& x)
1039 {
1040 if (s.opfx())
1041 x.printon(s);
1042 return s;
1043 }
1044
1045 void BitSet::printon(ostream& os, char f, char t, char star) const
/* [<][>][^][v][top][bottom][index][help] */
1046 // FIXME: Does not respect s.width()!
1047 {
1048 trim(rep);
1049 register streambuf* sb = os.rdbuf();
1050 const _BS_word* s = rep->s;
1051 const _BS_word* top = &(s[rep->len - 1]);
1052
1053 while (s < top)
1054 {
1055 _BS_word a = *s++;
1056 for (int j = 0; j < BITSETBITS; ++j)
1057 {
1058 sb->sputc((a & 1)? t : f);
1059 a >>= 1;
1060 }
1061 }
1062
1063 if (!rep->virt)
1064 {
1065 _BS_word a = *s;
1066 if (rep->len != 0)
1067 {
1068 for (int j = 0; j < BITSETBITS && a != 0; ++j)
1069 {
1070 sb->sputc((a & 1)? t : f);
1071 a >>= 1;
1072 }
1073 }
1074 sb->sputc(f);
1075 }
1076 else
1077 {
1078 _BS_word a = *s;
1079 _BS_word mask = ONES;
1080 _BS_word himask = MASK1(BITSETBITS - 1) - 1;
1081 if (rep->len != 0)
1082 {
1083 for (int j = 0; j < BITSETBITS && a != mask; ++j)
1084 {
1085 sb->sputc((a & 1)? t : f);
1086 a = (a >> 1) & himask;
1087 mask = (mask >> 1) & himask;
1088 }
1089 }
1090 sb->sputc(t);
1091 }
1092
1093 sb->sputc(star);
1094 }
1095
1096 int BitSet::OK() const
/* [<][>][^][v][top][bottom][index][help] */
1097 {
1098 int v = rep != 0; // have a rep
1099 v &= rep->len <= rep->sz; // within bounds
1100 v &= rep->virt == 0 || rep->virt == 1; // valid virtual bit
1101 if (!v) error("invariant failure");
1102 return v;
1103 }
1104