⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitset.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 1988 Free Software Foundation    written by Doug Lea (dl@rocky.oswego.edu)This file is part of the GNU C++ Library.  This library is freesoftware; you can redistribute it and/or modify it under the terms ofthe GNU Library General Public License as published by the FreeSoftware Foundation; either version 2 of the License, or (at youroption) any later version.  This library is distributed in the hopethat it will be useful, but WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.  See the GNU Library General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.*//*   BitSet class implementation */#ifdef __GNUG__#pragma implementation#endif#include <BitSet.h>#include <std.h>#include <limits.h>#include <Obstack.h>#include <AllocRing.h>#include <new.h>#include <builtin.h>#include <string.h>#include <strstream.h>void BitSet::error(const char* msg) const{  (*lib_error_handler)("BitSet", msg);}//  globals & constantsBitSetRep  _nilBitSetRep = { 0, 1, 0, {0} }; // nil BitSets point here#define ONES               ((unsigned short)(~0L))#define MAXBitSetRep_SIZE  ((1 << (sizeof(short)*CHAR_BIT - 1)) - 1)#define MINBitSetRep_SIZE  16#ifndef MALLOC_MIN_OVERHEAD#define MALLOC_MIN_OVERHEAD     4#endif// break things up into .s indices and positions// mask out bits from leftstatic inline unsigned short lmask(int p){  return ONES << p;}// mask out high bitsstatic inline unsigned short rmask(int p){  return ONES >> (BITSETBITS - 1 - p);}inline static BitSetRep* BSnew(int newlen){  unsigned int siz = sizeof(BitSetRep) + newlen * sizeof(short)     + MALLOC_MIN_OVERHEAD;  unsigned int allocsiz = MINBitSetRep_SIZE;;  while (allocsiz < siz) allocsiz <<= 1;  allocsiz -= MALLOC_MIN_OVERHEAD;  if (allocsiz >= MAXBitSetRep_SIZE * sizeof(short))    (*lib_error_handler)("BitSet", "Requested length out of range");      BitSetRep* rep = (BitSetRep *) new char[allocsiz];  memset(rep, 0, allocsiz);  rep->sz = (allocsiz - sizeof(BitSetRep) + sizeof(short)) / sizeof(short);  return rep;}BitSetRep* BitSetalloc(BitSetRep* old, const unsigned short* src, int srclen,                int newvirt, int newlen){  if (old == &_nilBitSetRep) old = 0;  BitSetRep* rep;  if (old == 0 || newlen >= old->sz)    rep = BSnew(newlen);  else    rep = old;  rep->len = newlen;  rep->virt = newvirt;  if (srclen != 0 && src != rep->s)    memcpy(rep->s, src, srclen * sizeof(short));  // BUG fix: extend virtual bit! 20 Oct 1992 Kevin Karplus  if (rep->virt)      memset(&rep->s[srclen], ONES, (newlen - srclen) * sizeof(short));  if (old != rep && old != 0) delete old;  return rep;}BitSetRep* BitSetresize(BitSetRep* old, int newlen){  BitSetRep* rep;  if (old == 0 || old == &_nilBitSetRep)  {    rep = BSnew(newlen);    rep->virt = 0;  }  else if (newlen >= old->sz)  {    rep = BSnew(newlen);    memcpy(rep->s, old->s, old->len * sizeof(short));    rep->virt = old->virt;    // BUG fix: extend virtual bit!  20 Oct 1992 Kevin Karplus    if (rep->virt)	memset(&rep->s[old->len], ONES, (newlen - old->len) * sizeof(short));    delete old;  }  else    rep = old;  rep->len = newlen;  return rep;}// same, for straight copyBitSetRep* BitSetcopy(BitSetRep* old, const BitSetRep* src){  BitSetRep* rep;  if (old == &_nilBitSetRep) old = 0;  if (src == 0 || src == &_nilBitSetRep)  {    if (old == 0)      rep = BSnew(0);    else      rep = old;    rep->len = 0;    rep->virt = 0;  }  else if (old == src)     return old;   else   {    int newlen = src->len;    if (old == 0 || newlen > old->sz)    {      rep = BSnew(newlen);      if (old != 0) delete old;    }    else      rep = old;    memcpy(rep->s, src->s, newlen * sizeof(short));    rep->len = newlen;    rep->virt = src->virt;  }  return rep;}// remove unneeded top bitsinline static void trim(BitSetRep* rep){  int l = rep->len;  unsigned short* s = &(rep->s[l - 1]);  if (rep->virt == 0)    while (l > 0 && *s-- == 0) --l;  else    while (l > 0 && *s-- == ONES) --l;  rep->len = l;}int operator == (const BitSet& x, const BitSet& y){  if (x.rep->virt != y.rep->virt)    return 0;  int xl = x.rep->len;  int yl = y.rep->len;  unsigned short* xs = x.rep->s;  unsigned short* ys = y.rep->s;  if (xl<=yl)    {      if (memcmp((void*)xs, (void*)ys, xl * sizeof(short)))  	return 0;      for (register int i=xl; i<yl; i++)        if (ys[i])	  return 0;      return 1;    }  else    {      if (memcmp((void*)xs, (void*)ys, yl * sizeof(short)))  	return 0;      for (register int i=yl; i<xl; i++)        if (xs[i]) 	  return 0;      return 1;    }}int operator <= (const BitSet& x, const BitSet& y){  if (x.rep->virt > y.rep->virt)    return 0;  int xl = x.rep->len;  int yl = y.rep->len;   unsigned short* xs = x.rep->s;  unsigned short* ys = y.rep->s;  unsigned short* topx = &(xs[xl]);  unsigned short* topy = &(ys[yl]);  while (xs < topx && ys < topy)  {    unsigned short a = *xs++;    unsigned short b = *ys++;    if ((a | b) != b)      return 0;  }  if (xl == yl)    return x.rep->virt <= y.rep->virt;  else if (xl < yl)    return !x.rep->virt;  else    return y.rep->virt;}int operator < (const BitSet& x, const BitSet& y){  if (x.rep->virt > y.rep->virt)    return 0;  int xl = x.rep->len;  int yl = y.rep->len;  unsigned short* xs = x.rep->s;  unsigned short* ys = y.rep->s;  unsigned short* topx = &(xs[xl]);  unsigned short* topy = &(ys[yl]);  int one_diff = 0;  while (xs < topx && ys < topy)  {    unsigned short a = *xs++;    unsigned short b = *ys++;    unsigned short c = a | b;    if (c != b)      return 0;    else if (c != a)      one_diff = 1;  }  if (xl == yl)    return x.rep->virt < y.rep->virt ||       (one_diff && x.rep->virt == y.rep->virt);  else if (xl < yl)    return !x.rep->virt;  else    return y.rep->virt;}int BitSet::empty() const{  if (rep->virt == 1)    return 0;  unsigned short* bots = rep->s;  unsigned short* s = &(bots[rep->len - 1]);  while (s >= bots) if (*s-- != 0) return 0;  return 1;}int BitSet::count(int b) const{  if (b == rep->virt)    return -1;  int l = 0;  unsigned short* s = rep->s;  unsigned short* tops = &(s[rep->len]);  if (b == 1)  {    while (s < tops)    {      unsigned short a = *s++;      for (int i = 0; i < BITSETBITS && a != 0; ++i)      {        if (a & 1)          ++l;        a >>= 1;      }    }  }  else  {    unsigned short maxbit = 1 << (BITSETBITS - 1);    while (s < tops)    {      unsigned short a = *s++;      for (int i = 0; i < BITSETBITS; ++i)      {        if ((a & maxbit) == 0)          ++l;        a <<= 1;      }    }  }  return l;}BitSetRep* BitSetcmpl(const BitSetRep* src, BitSetRep* r){  r = BitSetcopy(r, src);  r->virt = !src->virt;  unsigned short* rs = r->s;  unsigned short* topr = &(rs[r->len]);  if (r->len == 0)    *rs = ONES;  else  {    while (rs < topr)    {      unsigned short cmp = ~(*rs);      *rs++ = cmp;    }  }  trim(r);  return r;}BitSetRep* BitSetop(const BitSetRep* x, const BitSetRep* y,                     BitSetRep* r, char op){  int xrsame = x == r;  int yrsame = y == r;  int xv = x->virt;  int yv = y->virt;  int xl = x->len;  int yl = y->len;  int rl = (xl >= yl)? xl : yl;  r = BitSetresize(r, rl);  unsigned short* rs = r->s;  unsigned short* topr = &(rs[rl]);  int av, bv;  const unsigned short* as;  const unsigned short* topa;  const unsigned short* bs;  const unsigned short* topb;    if (xl <= yl)  {    as = (xrsame)? r->s : x->s;    av = xv;    topa = &(as[xl]);    bs = (yrsame)? r->s : y->s;    bv = yv;    topb = &(bs[yl]);  }  else  {    as = (yrsame)? r->s : y->s;    av = yv;    topa = &(as[yl]);    bs = (xrsame)? r->s : x->s;    bv = xv;    topb = &(bs[xl]);    if (op == '-')              // reverse sense of difference      op = 'D';  }  switch (op)  {  case '&':    r->virt = av & bv;    while (as < topa) *rs++ = *as++ & *bs++;    if (av)      while (rs < topr) *rs++ = *bs++;    else      while (rs < topr) *rs++ = 0;    break;  case '|':    r->virt = av | bv;    while (as < topa) *rs++ = *as++ | *bs++;    if (av)      while (rs < topr) *rs++ = ONES;    else      while (rs < topr) *rs++ = *bs++;    break;  case '^':    r->virt = av ^ bv;    while (as < topa) *rs++ = *as++ ^ *bs++;    if (av)      while (rs < topr) *rs++ = ~(*bs++);    else      while (rs < topr) *rs++ = *bs++;    break;  case '-':    r->virt = av & ~(bv);    while (as < topa) *rs++ = *as++ & ~(*bs++);    if (av)      while (rs < topr) *rs++ = ~(*bs++);    else      while (rs < topr) *rs++ = 0;    break;  case 'D':    r->virt = ~(av) & (bv);    while (as < topa) *rs++ = ~(*as++) & (*bs++);    if (av)      while (rs < topr) *rs++ = 0;    else      while (rs < topr) *rs++ = *bs++;    break;  }  trim(r);  return r;}void BitSet::set(int p){  if (p < 0) error("Illegal bit index");  int index = BitSet_index(p);  int pos   = BitSet_pos(p);  if (index >= rep->len)  {    if (rep->virt)      return;    else      rep = BitSetresize(rep, index+1);  }  rep->s[index] |= (1 << pos);}void BitSet::clear(){  if (rep->len > 0) memset(rep->s, 0, rep->sz * sizeof(short));  rep->len = rep->virt = 0;}void BitSet::clear(int p){  if (p < 0) error("Illegal bit index");  int index = BitSet_index(p);  if (index >= rep->len)  {    if (rep->virt == 0)      return;    else      rep = BitSetresize(rep, index+1);  }  rep->s[index] &= ~(1 << BitSet_pos(p));}void BitSet::invert(int p){  if (p < 0) error("Illegal bit index");  int index = BitSet_index(p);  if (index >= rep->len) rep = BitSetresize(rep, index+1);  rep->s[index] ^= (1 << BitSet_pos(p));}void BitSet::set(int from, int to){  if (from < 0 || from > to) error("Illegal bit index");  int index1 = BitSet_index(from);  int pos1   = BitSet_pos(from);    if (rep->virt && index1 >= rep->len)    return;  int index2 = BitSet_index(to);  int pos2   = BitSet_pos(to);  if (index2 >= rep->len)    rep = BitSetresize(rep, index2+1);  unsigned short* s = &(rep->s[index1]);  unsigned short m1 = lmask(pos1);  unsigned short m2 = rmask(pos2);  if (index2 == index1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -