## 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] */