bitset.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 805 行 · 第 1/2 页
CPP
805 行
void CL_BitSet::MakeEmpty ()
{
if (!PrepareToChange())
return;
ulong* p = _rep;
for (long i = 0; i < _count; i++)
*p++ = (ulong) 0;
_size = 0;
Notify();
}
// Make this the universal set:
void CL_BitSet::MakeUniversal ()
{
if (!PrepareToChange())
return;
register ulong* p = _rep;
for (register long i = 0; i < _count; i++)
*p++ = (ulong) (-1);
_size = __Mul32 (_count);
Notify();
}
bool CL_BitSet::IsUniversal () const
{
return Size() == __Mul32 (_count);
}
CL_IntegerSet CL_BitSet::AsSet () const
{
CL_IntegerSet aSet;
long offset = 0;
for (long i = 0; i < _count; i++, offset += BitsInLong) {
register ulong mask = 1;
register ulong data = _rep[i];
for (short j = 0; j < BitsInLong; j++) {
if (data & mask)
aSet.Add (offset + j);
mask <<= 1;
}
}
return aSet;
}
CL_BitSet& CL_BitSet::operator = (const CL_BitSet& o)
{
if (!PrepareToChange())
return *this;
if (_count != o._count) {
delete [] _rep;
_rep = new ulong[_count = o._count];
if (!_rep) {
_count = 0;
return *this;
}
}
for (long i = 0; i < _count; i++)
_rep[i] = o._rep[i];
_size = o._size;
Notify();
return *this;
}
static void DoOr (ulong& w1, ulong w2)
{
w1 |= w2;
}
static void DoAnd (ulong& w1, ulong w2)
{
w1 &= w2;
}
static void DoDiff (ulong& w1, ulong w2)
{
w1 &= ~w2;
}
CL_BitSet CL_BitSet::_DoOp (const CL_BitSet& s, void (*opr)(ulong&, ulong))
const
{
long cnt = maxl (s._count, _count);
ulong* new_rep = new ulong[cnt];
if (! new_rep)
return *this; // No memory
long i;
for (i = 0; i < cnt; i++)
new_rep[i] = (i < _count) ? _rep[i] : 0;
for (i = 0; i < s._count; i++) {
(*opr) (new_rep[i], s._rep[i]);
}
CL_BitSet o (cnt, new_rep);
return o;
}
// Union:
CL_BitSet CL_BitSet::operator + (const CL_BitSet& s) const
{
return _DoOp (s, DoOr);
}
// Difference:
CL_BitSet CL_BitSet::operator - (const CL_BitSet& s) const
{
return _DoOp (s, DoDiff);
}
// Intersection:
CL_BitSet CL_BitSet::operator * (const CL_BitSet& s) const
{
return _DoOp (s, DoAnd);
}
// Complement:
CL_BitSet CL_BitSet::operator ~ () const
{
CL_BitSet s (*this);
for (long i = 0; i < _count; i++)
s._rep[i] = ~s._rep[i];
s._size = s._count * BitsInLong - _size;
return s;
}
// CL_Set<long> CL_BitSet::operator + (const CL_Set<long>& s) const
// {
// CL_Set<long> t = s;
// for (long i = 0; i < _count; i++) {
// ulong b = _rep[i];
// for (short j = 0; j < BitsInLong; j++) {
// if (b & 1)
// t.Add (i*BitsInLong + j);
// b >>= 1;
// }
// }
// return t;
// }
//
//
//
// // Difference:
// CL_Set<long> CL_BitSet::operator - (const CL_Set<long>& s) const
// {
// CL_Set<long> t;
// for (long i = 0; i < _count; i++) {
// ulong b = _rep[i];
// for (short j = 0; j < BitsInLong; j++) {
// if (b & 1)
// t.Add (i*BitsInLong + j);
// b >>= 1;
// }
// }
// return t - s;
// }
//
//
//
// // Intersection:
// CL_Set<long> CL_BitSet::operator * (const CL_Set<long>& s) const
// {
// CL_Set<long> t;
// for (long i = 0; i < _count; i++) {
// ulong b = _rep[i];
// for (short j = 0; j < BitsInLong; j++) {
// if (b & 1)
// t.Add (i*BitsInLong + j);
// b >>= 1;
// }
// }
// return t * s;
// }
//
//
//
//
//
bool CL_BitSet::operator == (const CL_IntegerSet& o) const
{
if (Size() != o.Size())
return FALSE;
for (long i = 0; i < _count; i++) {
ulong b = _rep[i];
for (short j = 0; j < BitsInLong; j++) {
if (b & 1)
if (!o.Includes (i*BitsInLong + j))
return FALSE;
b >>= 1;
}
}
return TRUE;
}
bool CL_BitSet::operator == (const CL_BitSet& o) const
{
if (_size != o._size)
return FALSE;
for (long i = 0; i < minl (o._count, _count); i++) {
if (_rep[i] != o._rep[i])
return FALSE;
}
return TRUE;
}
bool CL_BitSet::IncludesAll (const CL_IntegerSet& o) const
{
long n = o.Size();
for (long i = 0; i < n; i++)
if (!Includes (o.ItemWithRank(i)))
return FALSE;
return TRUE;
}
bool CL_BitSet::IncludesAll (const CL_BitSet& o) const
{
if (_size < o._size)
return FALSE;
register long n;
if (o._count > _count) {
for (register long i = _count; i < o._count; i++)
if (o._rep[i] != 0)
return FALSE;
n = _count;
}
else
n = o._count; // n is the smaller of the two counts
for (register long i = 0; i < n; i++) {
register ulong p = _rep[i];
register ulong q = o._rep[i];
if (p | q != p)
return FALSE;
}
return TRUE;
}
// ------------------------ Save/restore -------------------------
long CL_BitSet::StorableFormWidth() const
{
return sizeof (CL_ClassId) + sizeof (long) + sizeof (ulong) +
_count*sizeof (ulong);
}
bool CL_BitSet::ReadFrom (const CL_Stream& s)
{
if (!PrepareToChange())
return 0;
if (!ReadClassId (s))
return FALSE;
long new_count;
if (!s.Read (new_count))
return FALSE;
if (!s.Read (_size))
return FALSE;
if (new_count != _count) {
ulong* new_rep = new ulong [new_count];
if (!new_rep)
return FALSE; // No memory
if (_rep)
delete [] _rep;
_rep = new_rep;
_count = new_count;
}
if (!s.Read ((uchar*) _rep, _count*sizeof(ulong)))
return FALSE;
// _size = 0;
// for (long i = 0; i < _count; i++) {
// _size += BitCount (_rep[i]);
// }
Notify();
return TRUE;
}
bool CL_BitSet::WriteTo (CL_Stream& s) const
{
return s.Write (ClassId()) &&
s.Write (_count) && s.Write (_size) &&
s.Write ((uchar*) _rep, _count*sizeof(ulong));
}
// ---------------------- BitSetIterator methods ----------------------
CL_BitSetIterator::CL_BitSetIterator (const CL_BitSet& o)
: _set (o)
{
_count = _index = 0;
_tblIndex = 0;
}
void CL_BitSetIterator::Reset ()
{
_index = _count = 0;
_tblIndex = 0;
}
void CL_BitSetIterator::BeginFromRank (long l)
{
register ulong* p = _set._rep;
_count = maxl (0, l);
if (!p)
return;
register long i;
for (i = 0; i < _set._count; i++, p++) {
short q = BitCount (*p);
if (l < q) break;
l -= q;
}
_index = i;
if (i < _set._count) {
register ulong r = _set._rep[i];
register short j;
for (j = 0; j < BitsInLong; j++)
if (BitTable[j] & r) {
l--;
if (l < 0)
break;
}
_tblIndex = j;
}
}
bool CL_BitSetIterator::More () const
{
return _count < _set.Size();
}
long CL_BitSetIterator::Next ()
{
if (_count >= _set.Size())
return -1;
ulong* p = _set._rep;
while (_index < _set._count) {
ulong mask = BitTable[_tblIndex];
if (mask & p[_index]) break;
_tblIndex++;
if (_tblIndex >= BitsInLong) {
_tblIndex = 0;
_index++;
}
}
if (_index < _set._count) {
long ret = __Mul32 (_index) + _tblIndex;
_count++;
_tblIndex++;
if (_tblIndex >= BitsInLong) {
_tblIndex = 0;
_index++;
}
return ret;
}
return -1;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?