oscar64/oscar64/BitVector.h

334 lines
5.3 KiB
C++

#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
class BitVector
{
protected:
unsigned* bits;
unsigned mask;
int size, dwsize;
public:
BitVector(void);
BitVector(const BitVector& v);
BitVector(int size, bool set = false);
BitVector(int size, unsigned char * data);
BitVector& operator=(const BitVector& v);
~BitVector(void);
BitVector operator+(const BitVector v) const;
BitVector operator*(const int n) const;
BitVector operator|(const BitVector v) const;
BitVector operator&(const BitVector v) const;
BitVector operator~(void) const;
void Set(int n, bool b);
bool Get(int n) const;
int Size(void) const;
int DWSize(void) const;
void Copy(unsigned* bits) const;
};
inline BitVector::BitVector(void)
{
size = 0;
dwsize = 0;
bits = nullptr;
mask = 0;
}
inline BitVector::BitVector(const BitVector& v)
{
int i;
size = v.size;
dwsize = v.dwsize;
mask = v.mask;
if (dwsize)
bits = new unsigned[dwsize];
else
bits = nullptr;
for (i = 0; i < dwsize; i++) bits[i] = v.bits[i];
}
inline BitVector::BitVector(int size, unsigned char * data)
{
this->size = size;
dwsize = ((size + 31) >> 5);
if ((size & 31) == 0)
mask = 0xffffffff;
else
mask = (1 << (size & 31)) - 1;
if (dwsize)
bits = new unsigned[dwsize];
else
bits = nullptr;
if (size)
{
memcpy(bits, data, (size + 7) / 8);
}
}
inline BitVector::BitVector(int size, bool set)
{
int i;
this->size = size;
dwsize = ((size + 31) >> 5);
if ((size & 31) == 0)
mask = 0xffffffff;
else
mask = (1 << (size & 31)) - 1;
if (dwsize)
bits = new unsigned[dwsize];
else
bits = NULL;
if (size)
{
if (set)
{
for (i = 0; i < dwsize - 1; i++) bits[i] = ~0;
bits[dwsize - 1] = mask;
}
else
for (i = 0; i < dwsize; i++) bits[i] = 0;
}
}
inline BitVector& BitVector::operator=(const BitVector& v)
{
int i;
delete[] bits;
size = v.size;
dwsize = v.dwsize;
mask = v.mask;
if (dwsize)
bits = new unsigned[dwsize];
else
bits = NULL;
for (i = 0; i < dwsize; i++) bits[i] = v.bits[i];
return *this;
}
inline BitVector::~BitVector(void)
{
delete[] bits;
}
inline BitVector BitVector::operator+(const BitVector v) const
{
int i;
int s;
unsigned merge;
BitVector vv(size + v.size);
if (dwsize == 0)
{
for (i = 0; i < v.dwsize; i++)
vv.bits[i] = v.bits[i];
}
else if (v.dwsize == 0)
{
for (i = 0; i < dwsize; i++)
vv.bits[i] = bits[i];
}
else
{
s = size & 31;
if (s == 0)
{
for (i = 0; i < dwsize; i++)
vv.bits[i] = bits[i];
for (i = 0; i < v.dwsize; i++)
vv.bits[i + dwsize] = v.bits[i];
}
else
{
for (i = 0; i < dwsize - 1; i++)
vv.bits[i] = bits[i];
merge = bits[dwsize - 1] & mask;
for (i = 0; i < v.dwsize; i++)
{
vv.bits[i + dwsize - 1] = merge | (v.bits[i] << s);
merge = v.bits[i] >> (32 - s);
}
if (dwsize - 1 + v.dwsize < vv.dwsize)
vv.bits[dwsize - 1 + v.dwsize] = merge;
}
}
return vv;
}
inline BitVector BitVector::operator*(const int n) const
{
int i, j;
int s, dw;
unsigned merge;
BitVector vv(size * n);
if (n > 0)
{
dw = 0;
for (i = 0; i < dwsize - 1; i++)
vv.bits[dw++] = bits[i];
merge = bits[dwsize - 1] & mask;
for (j = 1; j < n; j++)
{
s = (size * j) & 31;
if (s == 0)
{
vv.bits[dw++] = merge;
for (i = 0; i < dwsize - 1; i++)
vv.bits[dw++] = bits[i];
merge = bits[dwsize - 1] & mask;
}
else
{
for (i = 0; i < dwsize - 1; i++)
{
vv.bits[dw++] = merge | (bits[i] << s);
merge = bits[i] >> (32 - s);
}
if (mask >> (32 - s))
{
vv.bits[dw++] = merge | (bits[i] << s);
merge = (bits[i] & mask) >> (32 - s);
}
else
{
merge |= (bits[i] & mask) << s;
}
}
}
if (dw < vv.dwsize)
vv.bits[dw++] = merge;
assert(dw <= vv.dwsize);
}
return vv;
}
inline BitVector BitVector::operator|(const BitVector v) const
{
int i;
if (dwsize < v.dwsize)
{
BitVector vv(v.size);
for (i = 0; i < dwsize; i++) vv.bits[i] = bits[i] | v.bits[i];
for (i = dwsize; i < v.dwsize; i++) vv.bits[i] = v.bits[i];
return vv;
}
else
{
BitVector vv(size);
for (i = 0; i < v.dwsize; i++) vv.bits[i] = bits[i] | v.bits[i];
for (i = v.dwsize; i < dwsize; i++) vv.bits[i] = bits[i];
return vv;
}
}
inline BitVector BitVector::operator&(const BitVector v) const
{
int i;
if (dwsize < v.dwsize)
{
BitVector vv(v.size);
for (i = 0; i < dwsize; i++) vv.bits[i] = bits[i] & v.bits[i];
return vv;
}
else
{
BitVector vv(size);
for (i = 0; i < v.dwsize; i++) vv.bits[i] = bits[i] & v.bits[i];
return vv;
}
}
inline BitVector BitVector::operator~(void) const
{
int i;
BitVector vv(size);
for (i = 0; i < dwsize - 1; i++) vv.bits[i] = ~bits[i];
vv.bits[dwsize - 1] = ~bits[dwsize - 1] & mask;
return vv;
}
inline void BitVector::Set(int n, bool b)
{
if (b)
bits[n >> 5] |= (1 << (n & 31));
else
bits[n >> 5] &= ~(1 << (n & 31));
}
inline bool BitVector::Get(int n) const
{
return (bits[n >> 5] & (1 << (n & 31))) != 0;
}
inline int BitVector::Size(void) const
{
return size;
}
inline int BitVector::DWSize(void) const
{
return dwsize;
}
inline void BitVector::Copy(unsigned* bits) const
{
int i;
if (dwsize > 0 && (size & 31))
this->bits[dwsize - 1] &= (1 << (size & 31)) - 1;
for (i = 0; i < dwsize; i++)
{
bits[i] = this->bits[i];
}
}