modules/up/src/gnug++/BitSet.cc

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. error
  2. MASK1
  3. lmask
  4. rmask
  5. BSnew
  6. BitSetalloc
  7. BitSetresize
  8. BitSetcopy
  9. trim
  10. lcompare
  11. empty
  12. count
  13. BitSetcmpl
  14. BitSetop
  15. set
  16. clear
  17. clear
  18. invert
  19. set
  20. clear
  21. invert
  22. test
  23. next
  24. prev
  25. last
  26. BitSettoa
  27. shorttoBitSet
  28. longtoBitSet
  29. atoBitSet
  30. atoBitSet
  31. printon
  32. 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 

/* [<][>][^][v][top][bottom][index][help] */